Code Monkey home page Code Monkey logo

brick's Issues

Mouse support

Now that Vty has mouse support, there are some interesting possibilities for mouse support in Brick.

trailing newline on rendered list elements disrupts layout

The right-padding issue I noticed on #7 was because my rendered list elements had a trailing newline. In this situation the row ends with an ellipsis, and an enclosing element's width is disrupted on that line. Eg instead of

|                        |
|    E                   |
|                        |

you see

|                        |
|    E…|
|                        |

Perhaps it should always strip trailing newlines, I expect it will be a common mistake.

Support list paging operations

The list event handler needs to support paging operations. However, to do this, the event handling code needs to know about the viewport state from the most recent rendering pass. This is a blind spot in the current design but it can be done, and luckily this is a specific case of a more general problem of event handlers needing to consider rendering state in their decisions. Here's my plan:

  • Move EventM to Brick.Types
  • Make handleEvent run in EventM (This has the large added benefit of giving event handlers everywhere access to IO, which would make a lot of sense for use cases I can think of)
  • Make EventM a ReaderT over the recent viewport states
  • Add combinators to make lens-based operations cleaner since these changes would make handleEvent unwieldy; instead of
v <- handleEvent (st^.stuff) someEvent
continue $ st^.stuff .~ v

we'd have

continue =<< handleEventLensed st stuff someEvent

handleEventLensed :: (HandleEvent a) => s -> Lens' s a -> Event -> EventM s
handleEventLensed s func ev = do
  newVal <- handleEvent (s^.func) ev
  return $ s^.func .~ newVal
  • Add EventM functions for easy viewport state lookup
  • Add event handlers to list for paging operations using viewport state

(CC @simonmichael)

`halt` doesn't act like mzero

Hi, I've been playing around with brick a bit and I've noticed that halt doesn't behave like mzero. I'd like to write code that looks something like:

myHandler :: MyState -> Event -> EventM (Next MyState)
myHandler st evt = do
    when (evt `isKey` KEsc) $
        halt st

    ... further event handling ...

This is actually a somewhat larger problem for me than just when vs. if-then-else: I'd like to write composable, locally stateful event handlers using auto or similar, and step them forward in the top-level event handler them. However, currently I have no way of "inspecting" the return type of a handler (Next MyState) to see if indeed I should halt or continue.

I can easily work around this by defining my own ADT that encodes how to proceed, but it would essentially be almost identical to what already exists: either Continue or Halt.

Does this make sense? Thanks!

Crashes when use hCenter, hLimit, and vBox together.

The following program crashes when the terminal width is less than max (min hlim a) (min hlim b), and this happens both when the initial terminal size is too small and when I manually resize terminal width after program start.

import Brick
import Brick.Widgets.Center

ui :: Widget
ui = hCenter . hLimit hlim $ vBox [s a 'A', s b 'B']
    where
    s x c = str . take x $ repeat c
    hlim = 100
    a = 60
    b = 40

main :: IO ()
main = simpleMain ui

The error I got is Main.hs: row 0 now exceeds region width.

Not sure if this is a duplicate of #47 .

Padding doesn't affect available width/height

Hi,

When a widget is padded, its available width and height don't seem to change. Is this intended? Presumably widgets need correct information.

Examples:

w :: Widget
w = Widget Fixed Fixed $ do
    c <- getContext
    render (str (show (availWidth c)))

-- shows "123"
main = simpleMain w

-- shows "          123"
main = simpleMain (padLeft (Pad 10) w)

Crash when emptying out lists

I can reproduce a crash from within vty with the message "cannot crop height to less than zero". I don't know if this is a vty or a brick problem, but I'll report it here:

Make a list with many entries, select one that wouldn't be initially visible and then empty the list (and set the selected element to Nothing).

Quickstart:

git clone https://github.com/rootzlevel/brick-reproduce
cd brick-reproduce
stack build --exec brick-reproduce

Then type any letter (e.g. f) to empty the list.

Here is the code:

{-# LANGUAGE OverloadedStrings #-}
module Main where

import           Brick
import           Brick.Widgets.List
import           Control.Lens ((&), (.~))
import           Control.Monad (void)
import qualified Data.Vector as V
import           Graphics.Vty

type AppState = List String

event :: AppState -> Event -> EventM (Next AppState)
event l e = case e of
  EvKey (KChar 'q') [] -> halt l
  EvKey _ _ -> continue $ l & listElementsL .~ V.empty
                            & listSelectedL .~ Nothing
  _ -> continue l

main :: IO ()
main = do

  let app = App { appDraw = \l -> [renderList l (const str)]
                , appChooseCursor = showFirstCursor
                , appHandleEvent = event
                , appAttrMap = const (attrMap defAttr [])
                , appLiftVtyEvent = id
                , appStartEvent = return
                }

      initList = list "list" (V.fromList [show x | x <- [1..500]]) 1
                   & listSelectedL .~ Just 400


  void $ defaultMain app initList

lens usability improvements, examples ?

(micro)lens seems desirable for working with nested records in a brick app. I just started to exploring this, and am finding it harder than expected. Notes so far:

  • The first thing I want to use is (^.). Apparently this requires that the types it accesses are monoids. My records have brick Lists in them. You can't derive a Monoid instance for List because the constructors are hidden. I defined one manually for now:
instance Monoid (List a)
  where
    mempty      = list "" V.empty 1
    mappend a b = a & listElementsL .~ (a^.listElementsL <> b^.listElementsL)
  • I found myself wanting listSelectedElementL (and wrongly guessing listSelectedL was it).

re-initializing Editor widget with contents results in cursor being stuck at 1st line

Example (apply this diff to EditDemo.hs):

diff --git a/programs/EditDemo.hs b/programs/EditDemo.hs
index f300f88..05ad2f0 100644
--- a/programs/EditDemo.hs
+++ b/programs/EditDemo.hs
@@ -62,6 +62,7 @@ appEvent st ev =
         V.EvKey V.KEsc [] -> M.halt st
         V.EvKey (V.KChar '\t') [] -> M.continue $ switchEditors st
         V.EvKey V.KBackTab [] -> M.continue $ switchEditors st
+        V.EvKey (V.KChar ' ') [] -> M.continue st { _edit2 = (E.editor secondEditor (str . unlines) Nothing "hello\nworld")}
         _ -> M.continue =<< T.handleEventLensed st (currentEditorL st) ev

 initialState :: St

Then run it, press "TAB" (optional), then press SPACE to re-initialize/modify the 2nd editor widget to have the contents "hello\nworld". Although the words are rendered correctly (world being on the 2nd line), the cursor thinks that it's all on one line. It looks as if the cursor is hovering over extra blank space if you press Right arrow, but that appears to be the buffer where the word world is stored.

Tested on the latest 0.6.1 version by using cabal sandbox on GHC 7.10.3.

inconsistent scroll position after listMoveTo

On a particular screen, the items are ordered by date, so on entering it I move the selection to the last (most recent) item:

initRegisterScreen d args st@AppState{aopts=opts, ajournal=j, aScreen=s@RegisterScreen{}} =
  st{aScreen=s{rsState=is'}}
  where
    is' =
      listMoveTo (length items) $
      list (Name "register") (V.fromList items) 1
    items = ...

Sometimes the selected item appears at the bottom of the screen; sometimes it appears at the top (and I have to scroll up to see that there are older items). I'm not sure what controls this.

In this situation I think I'd like it to scroll down from the top just enough to reveal the selected item at the bottom of the screen.

Ideally I suppose there would be API to control List's scroll state (maybe it can expose a ViewportScroll ?)

Can not readLine

brick causes some strage behaviour whith stdin
In this program (only little different from the hello world example) I read a String from stdin and display it.

module Main where
import Brick.Widgets.Core (str)
import Brick.Main (simpleMain)

main :: IO ()
main = do
  --text <- return "Hello world"
  text <- getLine
  simpleMain . str $ text

No big deal, right?
Wenn I do

ghc -threaded hello.hs
./hello
> hello you

everything works nicely ("hello you" is displayed).
But for

ghc -threaded hello.hs
echo "hello you" | ./hello

which should provide the same result, an error occurs (which wasn't noticed at compiletime, this never happend to me before):

hello: getTerminalAttributes: illegal operation (Inappropriate ioctl for device)

I don't get problems when replacing the simpleMain . str with putStrLn, so I guess this is a problem of brick. I am running ghc 7.10.2 on an Arch Linux and tried xterm, urxvt and termite (all with the same result.
Any idea what happens here?

Multi-line markup

Hi, not sure if this behavior is intended...

{-# LANGUAGE OverloadedStrings #-}

-- hi
-- there
main = simpleMain (txt "hi\nthere")

-- hi...
main = simpleMain (markup ("hi\nthere" @@ bg blue))

Multi-line markdown appears to just put an ellipsis where the first newline should go.

Scrolling a list widget that isn't at the top of the screen can result in an off-screen selected item

The program I'm working on has a list widget, but above the list widget are a fixed number of lines of plain-old text. The presence of those header lines seems to screw up the scrolling/visibility logic a bit.

Terminal version: iTerm2 2.1.1 and Terminal 2.5.3 (both on OS X Yosemite)
GHC version: 7.10.2
brick version: 0.2
vty version: 5.4.0
A simple repro program: https://github.com/ktvoelker/brick-demo

Steps to reproduce:

  1. Run the program
  2. Press the Down key until the last visible item is selected.
  3. Press the Down key one more time.
  4. An item is selected which is not visible.

Expected behavior:
4. The list scrolls and the item becomes visible.

Note that if you press Down a few more times, eventually the list does start scrolling in the right direction. But it never catches up, so the selected item is always off-screen. The size of this "offset" appears to be equal to the number of lines of header text, plus one.

I would be glad to work on fixing the bug myself, but I wanted to make sure that it actually is a bug, first.

Add brick to stackage

Please consider adding brick to stackage. The package already builds fine with GHC 8 and the stackage resolver:

$ cabal unpack brick
$ cd brick-0.8
$ ghc --version
The Glorious Glasgow Haskell Compilation System, version 8.0.1
$ stack init --resolver nightly --force --solver
...
$ stack build
...
Registering brick-0.8...

ansi escape codes don't work

import Brick
import System.Console.ANSI -- ansi-terminal

main = simpleMain (str (setSGRCode [SetColor Foreground Dull Red] ++ "hi"))

For some reason, this displays ... instead of a red hi

incorrect size for widget between horizontal borders

      l = list ...
      border = borderWithLabel label
      hborder w = hBorderWithLabel label
                  <=>
                  w
                  <=>
                  hBorder
      ui1 = border l
      ui2 = hborder l

ui1 is a list inside a border; it is sized correctly. ui2 is the same list without the side borders; it overflows the bottom of the screen by one or two rows, so you can't see the bottom border or the bottom-most list row.

Cannot build : DSO missing from command line

I've encountered a weird issue when compiling brick demos.
I'm following the instructions in the README, and run cabal install -j -f demos.

TL;DR :

undefined reference to symbol 'del_curterm'
/lib64/libtinfow.so.6: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status

How to always "scroll to bottom"/"crop from top where necessary"?

I would like behaviour where lines grow from bottom to top, for a greedy widget. lets say there is space for 10 lines. If there is one line of content, i want it to be at the bottom. if there are 20 lines of contents, i want 11-20 displayed.

I have played around with viewports/adding empty lines/translating; nothing gave this exact behaviour. closest was invoking visible on the bottom line; but then the viewport remains translated even if the available space increases (again). (Also, this solution feels kinda hacky.)

Show instances for widgets would help debugging

I have been defining dummy Show instances for List, Editor etc. so that I can include them in my application types which need to be Showable for debugging, testing in GHCI etc.

instance Show (List a) where show _ = "<List>"
instance Show Editor   where show _ = "<Editor>"

key problems with Ctrl+arrow and Shift-tab in rxvt-unicode

Hello,

I use rxvt-unicode and running the brick demos I noticed

  • in edit demo tab moves to next edit but Shift-tab does not move to previous
  • in demos using Ctrl+arrow keys the part with Ctrl+arrow does not work

Using brick 0.4.1 on Debian Stretch

constraints: StateVar ==1.1.0.1,
adjunctions ==4.2.2,
array ==0.5.1.0,
base ==4.8.2.0,
base-orphans ==0.4.4,
bifunctors ==5,
binary ==0.7.5.0,
blaze-builder ==0.4.0.1,
bytestring ==0.10.6.0,
comonad ==4.2.7.2,
containers ==0.5.6.2,
contravariant ==1.3.3,
data-default ==0.5.3,
data-default-class ==0.0.1,
data-default-instances-base ==0.0.1,
data-default-instances-containers ==0.0.1,
data-default-instances-dlist ==0.0.1,
data-default-instances-old-locale ==0.0.1,
deepseq ==1.4.1.1,
directory ==1.2.2.0,
distributive ==0.4.4,
dlist ==0.7.1.2,
exceptions ==0.8.0.2,
filepath ==1.4.0.0,
free ==4.12.1,
ghc-prim ==0.4.0.0,
hashable ==1.2.3.3,
integer-gmp ==1.0.0.0,
kan-extensions ==4.2.3,
lens ==4.12.3,
mtl ==2.2.1,
old-locale ==1.0.0.7,
parallel ==3.2.0.6,
parsec ==3.1.9,
prelude-extras ==0.4.0.2,
pretty ==1.1.2.0,
primitive ==0.6.1.0,
profunctors ==5.1.1,
reflection ==2,
rts ==1.0,
semigroupoids ==5.0.0.4,
semigroups ==0.16.2.2,
stm ==2.4.4,
tagged ==0.8.2,
template-haskell ==2.10.0.0,
terminfo ==0.4.0.1,
text ==1.2.1.3,
text-zipper ==0.3.1,
time ==1.5.0.1,
transformers ==0.4.2.0,
transformers-compat ==0.4.0.4,
unix ==2.7.1.0,
unordered-containers ==0.2.5.1,
utf8-string ==1.0.1.1,
vector ==0.10.12.3,
void ==0.7.1,
vty ==5.3.1

Dialog widget fixed width seems problematic

That the dialog widget is parametrised with a fixed width makes it very hard to use in a way, that would preclude crashes on terminal resize.

Most other widgets are resize-agnostic, yet the dialog isn't.

Support optimized list rendering

Right now, the List rendering process utilizes the viewport feature to simplify scrolling state tracking. While that means the list supports variable-height list items, it means we pay a (possibly big) penalty since we render all list items regardless of visibility and then crop to show the ones in view. This works fine for small lists, but the delay in rendering becomes noticeable even for realistically sized lists (thousands of elements).

This clearly isn't great.

I initially thought supporting variable-height list items as well as uniform-height items would be a slam-dunk but I'm now thinking that an optimized list is really needed in the (common) case where you know that the heights of all of your list items will be the same number of rows. The only way we can know which subset of list elements to bother rendering is by knowing how high they will be in advance, a luxury we don't have if we assume the item heights can't be precomputed. But if we restrict ourselves to the assumption that the list items all have the same known height, we can use the scrolling state and viewport size to select only the items worth rendering.

I think this is feasible, but it might increase the burden on the user slightly and might have some trade-offs that need consideration. This ticket is a reminder for me to implement this and to jot down notes about what I have in mind.

(CC @simonmichael)

Get multiple, different colorized output for a list element

Not sure if this is a question or a feature request, but please bear with me.

From what I can tell, there is no way to assign multiple color attributes to text within a single List widget element.

What I have is basically a List of multiple strings, with each string being a particular "type", much like a spreadsheet. E.g.,

foo bar quux
foo bar quux
foo bar quux

and I want all the foo strings to be a certain color distinct from all the bar strings, and so on.

As I write this I realize that I could probably just have multiple List widgets, one for each "column" (one for foo, one for bar, etc.) and assign a different color attribute for each widget (and have them aligned horizontally, right?), but is there a way to just embed different colors into a single List widget item?
I feel that having multiple List widgets seems hacky and overly complicated.

Providing a frp interface

Looking at the App datatype, it seems to me that the interface could be expressed more concisely using some frp library such as reactive-banana or reflex. (And for users that otherwise already use some frp approach it needs a nasty layer between frp and the current state-passing interface.)

Has this been considered before? Do there exist any forks or other vty-reverse-deps that go in this direction?

Suggestion: Make Fixed widgets state their preferred size

To be precise, I'm suggesting that:

data Size = Fixed
    | Greedy

be changed to

data Size = Fixed Int
    | Greedy

with the semantics that Fixed n widgets take up n units of space, but will deal with less if they are given it, and Greedy widgets get given whatever is left over after space is allocated to Fixed widgets.

The benefits of the change are:

  • Forcing people to state/calculate the size of Fixed widgets, ensures that Fixed widgets actually have the correct semantics (this would have prevented #17, for example).
  • It makes boxRenderer much more modular, because it be implemented as:
    1. Calculate the amount of space to give each widget (which can be calculated from the amount of space available and the sizing of each widget)
    2. Render all the widgets
    3. Combine the results
  • Further to the previous point, implementing 2d tables becomes practical (the trick boxRenderer uses doesn't work in 2d)
  • It allows UI elements to degenerate in an orderly fashion when not given enough space. Currently the highest level boxRenderer just crops the resulting table. It would be more sensible if it instead rendered the sub-widgets with less space than requested.

The problems I can foresee are:

  • Every Fixed widget/combinator has to be changed. This is less bad than it seems. Every widget/combinator I found in the library can be implemented easily with the obvious Monoid and Ord instances for Size.
  • Programs that implement Fixed widgets directly are broken.

I'm happy to start implementing this, but I want to make sure you agree with basic idea first.

Unable to capture some modified key strokes.

I have a small demo using the following event loop

event :: State -> Event -> EventM (Next State)
event st e = do
    liftIO $ print e
    continue st

and the following draw function

draw :: State -> [Widget]
draw st = [str "Hello World!"]

There are several cases like Ctrl+,, Ctrl+., and Ctrl+/ that do not fire an event. Additionally there is at least one case of sending the wrong event. For example you would expect Ctrl+m to read...

EvKey (KChar 'm') [MCtrl]

however it actually reads...

EvKey KEnter []

Linux only?

brick-0.5 depends on unix-2.7.1.0 which failed to install

Is windows support planned?

Editor bugs

Right now editors are showing a mysterious '...' character as well as failing to show more than the first line of text when being rendered. This might be related to recent string function changes.

Brick visibility demo - ctrl-arrow up/down

The top-left and top-right viewports work as advertised. The bottom one does as expected for left-right movements, but ctrl-up/down arrows affect the top-left viewport instead of the bottom one.

brick version 0.1
vty-5.2.10 (as reported in my cabal sandbox's share/x86_64-osx-ghc-7.10.2 directory)

unsure where the output of cabal freeze goes.

Paste support in the Editor

The Editor widget can now be modified to support bracketed pastes from Vty more efficiently than processing input events individually.

Layers in Widget

Hi Jonathan,

thank you very much for the amazing "brick" library! It's great working with it. :)

I'm looking for a way to have layers within a "Widget", not just within an "App". I wondered if it would be possible to change the "image" in "Result" from "Image" to "[Image]", and then change "renderFinal" to flatten the "List" before passing it to "picForLayers"? Do you see any problems with that approach, and if not, would you be interested in integrating a patch if I would come up with the necessary changes?

Many thanks!

Transparency for layers/pad functions

Hi,

first of all: I really like how this library feels, great job!

However, I have some problems laying out stuff for an ascii game. Consider two widgets I want to place in the top-right and bottom-left corner, respectively. I'd like that to work independent from the bounds of the containing widget. Is there a way without asking the container for its current size, e.g. reusing the pad* functions or something? It should also be composable, e.g. if I add other widgets to the container it should not influence the positioning of the already specified widgets.

What I had in mind was similar to having a separate layer for each widget and then just pad* Max, but unfortunately the padding characters aren't transparent.

What it boils down to, I guess, is: Is there a notion of transparency?

Strange behavior when using hBox with unicode char

module Main where

import qualified Brick.Main as M
import qualified Brick.Widgets.Core as WC

ui = WC.vLimit h . WC.hLimit 5 $ WC.hBox
    [ WC.str text2 
    , WC.vLimit h $ WC.fill '$'
    ]
    where
    h = 3
    text1 = "    \n寬字\n    \n"
    text2 = "    \nabcd\n    \n"

main :: IO ()
main = M.simpleMain ui

The program displays

    $
abcd$
    $

But when I replace WC.str text2 by WC.str text1, it displays


寬字 

Both abcd and 寬字 occupy 4 display length in my terminal.
Maybe there is something wrong with wide character rendering?

Examples for more complex applications needed.

After reading the guide and looking at the example programs, I still have no idea how I am supposed to switch from one UI to another. For instance, I want to display a sublist after choosing a specific element of the main list and display a dialog after choosing a different element of the list. Is there any way to do that? I can do something similar by using multiple Apps like so

main = do
  a <- M.defaultMain listApp $ initialState ["subList1","subList2"]
  case (elem a) of
    Just (_,"subList1") -> M.defaultMain subList1App $ initialState [1..5]
    Just (_,"subList2") -> M.defaultMain subList2App $ initialState [5..10]

Now that works, but I don't think I'm supposed to use multiple Apps. Now I could just use the same App for everything, but then I can't use different header/footer for the different Lists without introducing a state datatype. Then there's also a problem when I want to go back from a sublist to the parent list. It would be nice if there was information on how to do these things.

Making strict widgets greedy

I’d like to make a list, like so:

124   foo
4324  bar
1     test

Padding just adds space to the side on each line, so the result becomes something like

124   foo
4324   bar
1   test

The idea is to make the left part greedy and then restrict its size.
My naive approach ((hLimit 10 $ (txt "124") { hSize = Greedy }) <+> txt "foo" gives

124foo
…

It looks to me like it doesn’t make sense to reset hSize without re-rendering (what hLimit does).
How would I set a txt or str to greedy?
Does it even make sense to export the fields of Widgets?

Stack lts version is 0.4.1

This is not necessarily a bug, I just wanted to notify you, that the brick version on stackage lts is 0.4.1, for which most examples don't work. The nightly version is up to date, however, but you might want to include a note about this in the manual.

Thanks for this library!

Space leak when app state accumulates?

Haskell memory leaks still confuse me, so this behavior might be expected from my code, but I’ve noticed that when application state is carried over between events, the heap blows up very fast. E. g., for a simple app which has state based on Text, and which appends 1k of text when each event fires, the heap size goes up very fast and memory will soon run out, even though only a linear amount of data is appended. If I change the txt resp. str widgets to only take as many lines and columns as available, the effect is reduced, but still present (so maybe the leak is with Vty, not Brick?).

This came up when I was trying to use a str widget to keep a log of incoming Vty events. After a few hundred lines the address space exceeded several GB.

I can reproduce this behavior with the following gist.

The following gives the heap profile for the gist after hammering away at the keys for a second.

graph

However, even though I should have library profiling enabled, neither the Vty or Brick modules appear in the graph, so it may well be it’s All My Fault™ after all. Maybe the issue makes more sense to you.

Thanks for making Brick!

`Eq` instances for Location and Cursor

I'm having to compare location quite often, and I'd like to avoid to define an orphan instance.
I can do the PR if you want (I believe ghc can derive Eq correctly anyway).
Any reason it's not there ?
(disclaimer, I'm fairly new to haskell)

Banners

Hi,

Thanks for a really cool lib.

I'm interested in sorta doing full width banners or headers.
I mean full width of the viewport.

I want to do the equivalent of this

screen shot 2016-05-09 at 3 51 33 pm

and color the background.

I know I can do this manually with spaces, but looking for a way to do it automatically to the 'edge of view' or something like that.

(Apologizes in advance, i'm new to both Brick and Haskell, but having a lot of fun so far)

Dropdown menu

Is there a need for a dropdown menu? I came across a few instances where it might come in handy and would love to give a shot at it.

Expose `nextButtonBy` for `Dialog` widget

This is a feature request to expose another way than handleDialogEvent to change the state of a dialog widget. It would be nice to have support for arrows as well as tab/s-tab, and maybe something else.

So maybe directly expose (and document) nextButtonBy or expose simplified functions like nextChoice and prevChoice of type Dialog -> Dialog to handle that manually.
What do you think ?

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.