Giter VIP home page Giter VIP logo

react-amphtml's Introduction

react-amphtml

Use amphtml components inside your React apps easily!

Usage

react-amphtml exports React components and functions to easily create AMP HTML pages. Each exported React component has a TypeScript interface and PropTypes derived from AMP HTML's own validator rules to speed up development and make it safer. Boilerplate and the inclusion of AMP directive-specific scripts is all handled for you!

// All AMP elements
import * as Amp from 'react-amphtml';

// Helper render props for actions and bindings
import * as AmpHelpers from 'react-amphtml/helpers';

// Components and functions to render pages
import {
  AmpScripts,
  AmpScriptsManager,
  headerBoilerplate,
} from 'react-amphtml/setup';

Amp Components

import * as Amp from 'react-amphtml';
// ...
<Amp.AmpCarousel {...props} />

The main file exported by react-amphtml contains all of the AMP HTML directives as React components. This includes the custom element amp-* directives, normal HTML directives with validations required by AMP, and some components with added functionality: Html, AmpState (amp-state directive) and Script.

To see a list of available components and their relative documentation see the official AMP components documentation: The AMP component catalogue.

Amp Helpers

import * as Amp from 'react-amphtml';
import * as AmpHelpers from 'react-amphtml/helpers';

// Example of attaching actions to elements
<AmpHelpers.Action events={{...}}>
  {(props) => (
    <button type="button" {...props}>
      Do Something
    </button>
  )}
</AmpHelpers.Action>

// Example of using state and bindings together
const defaultHeading = {
  text: 'Hello, World!',
};
// ...
<Amp.AmpState specName="amp-state" id="heading">
  {defaultHeading}
</Amp.AmpState>
<AmpHelpers.Bind text="heading.text">
  {(props): ReactElement => <h1 {...props}>{defaultHeading.text}</h1>}
</AmpHelpers.Bind>

The helpers file contains render prop components that help add AMP attribute directives for actions and bindings. Wondering what actions and bindings are all about? Check out these official guides on the subjects:

Amp Setup

import * as Amp from 'react-amphtml';
import {
  AmpScripts,
  AmpScriptsManager,
  headerBoilerplate,
} from 'react-amphtml/setup';

const ampScripts = new AmpScripts();

const bodyContent = renderToStaticMarkup(
  <AmpScriptsManager ampScripts={ampScripts}>
    <div>
      <Amp.AmpImg
        specName="default"
        src="/"
        width={0}
        height={0}
        layout="responsive"
        alt="test"
      />
      <Amp.AmpAccordion />
    </div>
  </AmpScriptsManager>,
);

/* eslint-disable react/no-danger */
const html = renderToStaticMarkup(
  <Amp.Html>
    <head>
      {headerBoilerplate('/')}
      <title>react-amphtml</title>
      {ampScripts.getScriptElements()}
    </head>
    <body dangerouslySetInnerHTML={{ __html: bodyContent }} />
  </Amp.Html>,
);
/* eslint-enable */

const htmlPage = `
  <!doctype html>
  ${html}
`;

The setup file makes creating pages for AMP HTML a breeze. It helps insert all the necessary boilerplate and also the scripts needed for AMP directives.

The code is based on the requirements from AMP documented in Create your AMP HTML page: Required mark-up.

Examples

Full Example

Go checkout ampreact!

If you are looking for an example that is in combination with one or more of these tools:

ampreact gives a very nice setup to get started with or learn from!

Simple Example

For simple usage examples of react-amphtml, check the Jest unit tests in react-amphtml/src/__tests__/react-amphtml.spec.tsx. The best test to look at is can server-side render valid html for a good complete usage of react-amphtml.

Development

About

The code for react-amphtml is generated from AMP HTML's own validator via amphtml-validator-rules.

Want to learn about AMP HTML validation? See the guide: Validate AMP pages.

Need to run the validator? Use either the online tool The AMP Validator or the npm package amphtml-validator.

Commands

Use the following commands to develop on react-amphtml.

  • npm run codegen: Create components based on AMP HTML's validator. This must be done at least once prior to running npm run build, and can be done afterwards anytime code in codegen is modified.

  • npm run build: Bundles the source files into dist.

  • npm run typecheck: Uses TypeScript to ensure type safety. Should be run after running npm run build to check the files in dist that are bundled.

  • npm run lint: Use ESLint to check source files.

  • npm run test: Use Jest to run tests.

Resources

react-amphtml's People

Contributors

defjosiah avatar dfrankland avatar lucasecdb 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  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  avatar  avatar

react-amphtml's Issues

Question

Hi, i have a ws return html from wordpress, i use ampify or html-to-amp . to transform html to valid amp source, later inject the result with DangerousHTML. All works fine, except, react-amphtml dont inject necessary scripts like amp-youtube, or other amp scripts.

My code

import React from 'react';
import Head from 'next/head';
import axios from "axios";
import urljoin from "url-join";
import assert from "assert";
import styled from 'styled-components';
import * as Amp from 'react-amphtml';
import setupHtmlToAmp from 'html-to-amp';
import DangerousHTML from 'react-dangerous-html';

const htmlToAmp = setupHtmlToAmp();

export default class Post extends React.Component {
//https://github.com/ampproject/amphtml/tree/master/extensions
constructor(props) {
super(props);
}

static async getInitialProps(context) {
try {
const url = urljoin("https://t9c4w6g7.stackpathcdn.com", "/post/", "71126");
const response = await axios.get(url);
const post = response.data;
post.test = await htmlToAmp(post.content.rendered);
//console.log(post.test)
//console.log(post.test)
assert(post);
//console.log(url);
console.log("Paso por aca.")
return { post };
} catch (e) {
//console.log("Post, not found", e);
//utils.handleNotFound(context, e);
}
}

render() {
const { post } = this.props;

const Container = styled.div`
 .embed-responsive {
    position: relative;
    height: 0;
    overflow: hidden;
  }
  .embed-responsive-16by9 {
      padding-bottom: 56.25%;
  }
  .embed-responsive-4by3 {
      padding-bottom: 75%;
  }
  .embed-responsive iframe {
      position: absolute;
      top:0;
      left: 0;
      width: 99%;
      height: 100%;
  }
`;

return (
  <Container>
    <Head>
      <title>{post.title.rendered}</title>
    </Head>
    <DangerousHTML tagName="h1" html={post.title.rendered} />
    <Amp.AmpVideoIframe
      specName="AMP-VIDEO-IFRAME[poster]"
      layout="responsive"
      width="16"
      height="9"
      src="http://localhost:9090/"
      poster=""
    />
    <DangerousHTML tagName="h2" html={post.excerpt.rendered} />
    <DangerousHTML tagName="p" html={post.test} />
    <h2>Articulos Relacionados</h2>
    <p>These articles might be interesting for you as well:</p>
  </Container>)

}
}

How i can put the scripts into Head, i am using stater project: https://github.com/dfrankland/ampreact

Thanks

Is there amp-access support?

Hi. I came across this project and was giving it a go. Is there amp-access support? To get this going you need to have a <script> tag in <head> holding the authentication information (JSON). You then also have to add amp-access and amp-access-hide attributes to elements around the place to hide/show them based on current access rights.

Thanks!

Suggestion: Make it easier to use in different ways, not always using styled components etc

Thanks for building this library. I was trying to use it to build a demo to teach AMP, but for non-React experts. So my goal is to have the React components look as much like plain AMP HTML as possible. That may not be your goal of course (in which case you can just close this), but feedback in case helpful.

  • I could not work out how to add extra <script> elements to the head. amp-access needs to do this for a lump of JSON for example.
  • I could not work out how to inline CSS not using 'styled-components'. I noticed the clever code to merge all the CSS together, but I wanted to use either straight CSS Stylesheets or CSS modules to make it look "less scary". I hacked in reading from .next/static/style.css for a quick test in combination with @zeit/next-css which worked, but I am sure there is a cleaner way to do it. It would be nice if it could suck in CSS as produced by several different strategies (not sure how feasible this is).
  • Is the special on attribute processing code needed? I just used an on attribute directly and it did not get stripped. Maybe React has changed since you first built the library? It is less scary for an AMP developer just type type in the raw on attribute rather than use the extra component.
  • AMP allows some attributes on all elements, in any context. E.g. amp-access is one such attribute, but there are others. That made me wonder whether it was better to just use raw HTML elements more in components (with CSS to style the divs). Or do you think a wrapper AMP access component would be better to annotate its children with additional attributes? (I assume that is what happens with the on element.)

I am not sure how interested you still are in these sorts of changes, but I was just evaluating it to see if could use it to build better componentized AMP demos. React is probably an overkill in some ways (more powerful and complex than required).

Just FYI: The project I was trying to port from Nuxt to Next was https://github.com/alankent/amp-nuxt-trial (a work in progress). The amp-access code was in https://github.com/alankent/amp-nuxt-trial/blob/master/components/SiteTitleBar.vue - but Nuxt/Vue has problems too like swallowing nested <template> elements. Using BEM CSS class names looks a bit verbose, but means you can steal the HTML and CSS and use on a different project without Vue if you want to... almost.

AmpList doesn't render [src] attribute

I'm trying to implement the example from here (under "Dynamic Related Product Lists")

My code:

<AmpHelpers.Bind src="myState.items">
        {props => (
          <Amp.AmpList
            id="show-more-list"
            specName="AMP-LIST [SRC]"
            layout="fixed-height"
            height="445"
            src="https://jsonplaceholder.typicode.com/posts"
            className="items m1"
            width="auto"
            {...props}
          >
            <template type="amp-mustache">
              <p>{"{{title}}"}</p>
            </template>
          </Amp.AmpList>
        )}
      </AmpHelpers.Bind>

renders:

          <amp-list id="show-more-list" layout="fixed-height" height="445"
                    src="https://jsonplaceholder.typicode.com/posts" width="auto" class="items m1">
            <template type="amp-mustache"><p>{{title}}</p></template>
          </amp-list>

As you can see [src] attribute is missing from <amp-list> in rendered html

React 16 issues

I want to move to React 16, on installation I get the following issue:

npm WARN [email protected] requires a peer of react@^15.6.2 || ^16.0.0 but none was installed.
npm WARN [email protected] requires a peer of react-dom@^15.6.2 || ^16.0.0 but none was installed.

And the following errors:

These dependencies were not found:

  • react-dom/lib/DOMProperty in ./node_modules/react-amphtml/dist/index.js
  • react-dom/lib/ReactInjection in ./node_modules/react-amphtml/dist/index.jsThis functionality is only used in whitelist(), tried to copy the index.js file from the react-amphtml package, remove the imports and remove the whitelist function, but that did not help...

Any help would be appreciated...

Amp-ad specName error with Server Side react with version 3.0.1

Hi, we recently updated our react-amphtml version to 3.0.1 and were implementing Amp-ads in our server-side React application.

After adding the AmpAd component in page we are getting the following error.
Warning: Failed prop type: Invalid prop specName of value amp-ad supplied to Script$$1, expected one of ["amphtml engine v0.js script","amp4ads engine amp4ads-v0.js script",

Here is what the React JSX looks like
<AmpAd specName={'default'} id={${adName}-${position}} type="doubleclick" data-slot={sitename} json={JSON.stringify({ targeting })} width={adDimensions[0]} height={adDimensions[1]} />

Changing the prop specName to spec-name resolves the error message but then introduces a new error at render time:
"Warning: Failed prop type: The prop specName is marked as required in AmpAd, but its value is undefined."

Is there a possible issue with the react amphtml specName with Amp-ads? If not, is there a solution to this issue? Thank you.

Unable to use AmpHelpers.bind

I have started integrating this library into my organisation's codebase. But I am facing one issue.

When I use the following example in my codebase:
<AmpHelpers.Bind text="'Hello ' + foo">
{props => <p {...props}>Hello World

}
</AmpHelpers.Bind>

I get the error:
Unknown prop [text] on <p> tag. Remove this prop from the element. For details, see https://fb.me/react-unknown-prop

Also, I don't see any [text] attribute on the HTML generated.

Is there any workaround for this? Using react v15.3

Error: "sidebar" is not a valid amphtml directive.

Hey, @dfrankland, while I was using react-amphtml plugin to create and use AMP's component inside my react set-up, I got stuck with amp-sidebar.
AmpSideBar = amphtml('sidebar', addScript)

Error: "sidebar" is not a valid amphtml directive. at reactAmpHtml (/Users/parvezshaikh/Sites/WEB/site/node_modules/react-amphtml/index.js:27:11)

Can you please guide me through this?

How to use `amp-lightbox-gallery` with Carousel?

I would like to use amp-lightbox-gallery with carousel. What's the right way to do it?

Nowadays I'm doing this:

<Amp.AmpCarousel width='1' height={aspectRatio} layout='responsive' type='slides' lightbox=''>
  {imageComponentList}
</Amp.AmpCarousel>

But the script for amp-lightbox-gallery isn't automatically imported:

<script async custom-element="amp-lightbox-gallery" src="https://cdn.ampproject.org/v0/amp-lightbox-gallery-0.1.js"></script>

How to pass props without value to component?

the problem

amp-accordion has an animate prop that I would like too add, but I don't find how to do it.

what I've tried

  1. set it as specified in the docs
<Amp.AmpAccordion animate>

renders

<amp-accordion animate="true" class="i-amphtml-element i-amphtml-layout-container i-amphtml-layout">

which is not a valid amp-html

  1. Set animate={null}
<Amp.AmpAccordion animate={null}>

renders

<amp-accordion class="i-amphtml-element i-amphtml-layout-container i-amphtml-layout">

Proper way to add analytics

Hi, first of all, excellent repo, I'm loving how everything works so well.

My issue is the following, in order to add segment I finally used a hack to add the script data. It works but clearly is not ideal.

This is my current code

<AmpAnalytics
    type="segment"
    dangerouslySetInnerHTML={{__html: '<script type="application/json">{"vars":{ "writeKey": "abc", "name": "cde" }}</script>'}}
  >
  </AmpAnalytics>

Any clue on how to do this less dangerously

Thanks!

amphtml ⚡attribute

The final code output does not include the in the html tag.

This throws an error (not just a warning) when validating the AMP document:
The mandatory attribute '⚡' is missing in tag 'html ⚡ for top-level html'. (see https://www.ampproject.org/docs/reference/spec#required-markup)

I am using the template from https://github.com/dfrankland/ampreact

AmpIframe does not support height and width and layout attributes.

Hello,

When trying to use layout, height and width attributes on AmpIframe I get Typescript error, saying that these properties do not exist in the respective type. After digging a little deeper, I found that the responsible type (AmpIframeProps) extends with generic type React.HTMLAttributes as opposed to React.IframeHTMLAttributes:

filename: amphtml.d.ts

export interface AmpIframeProps extends React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>,
HTMLElement> {
    allow?: string | undefined;
    allowfullscreen?: boolean | undefined;
    allowpaymentrequest?: boolean | undefined;
    ...

Screenshot 2020-10-02 at 15 39 37

AmpCarousel 0.2 "attribute 'version' may not appear"

Hey,
when passing version "0.2" to AmpCarousel. I get errors from the AMP Validation Service:

The attribute 'version' may not appear in tag 'AMP-CAROUSEL'.

At the same time im passing version "0.1" to an Amp-Carousel [lighbox]

The attribute 'version' may not appear in tag 'AMP-CAROUSEL lightbox'.

<AmpCarousel version="0.2" ... />

Is there a workaround?

At the same Time i want to use amp-carousel 0.2 but amp-lighbox-gallery 0.1

It seems that this is not possible.

When i set version to 0.2 on the normal AmpCarousel, and 0.1 on the AmpCarousel[lighbox]. The ScriptManager injects

<script async="" custom-element="amp-carousel" src="https://cdn.ampproject.org/v0/amp-carousel-0.1.js"></script>
<script async="" custom-element="amp-lightbox-gallery" src="https://cdn.ampproject.org/v0/amp-lightbox-gallery-0.1.js"></script>

If i set AmpCarousel[lighbox] to 0.2 the correct "amp-carousel" script gets injected. But i get the following AMP Validation Error:

The attribute 'src' in tag 'amp-lightbox-gallery extension .js script' is set to the invalid value 'https://cdn.ampproject.org/v0/amp-lightbox-gallery-0.2.js'.

Warning: Invalid attribute name: `⚡`

On adding react-amphtml to a nextjs project, everything seems to run fine but the following warning keeps getting thrown:
Warning: Invalid attribute name: ⚡`` .
What am I doing wrong?

I have reproduced the issue in the https://github.com/nahushf/next-amp-error repository.
react-amphtml has been configured in the _document.js file

Operating system:
Windows 10(Windows subsystem for linux)

Node JS version:
v8.12.0

What's specName and why is it necessary?

I've checked react-amphtml.spec.js and noticed that the AmpImg has a prop called specName.

        <div>
          <Amp.AmpImg specName="default" src="test" />
          <Amp.AmpPixel src="blah" />
        </div>

I've tried using this component (Amp.AmpImg) without setting this prop (specName) but it won't render a <amp-img> at runtime, so this props is mandatory.

Why is it necessary?

TypeScript types

I'm using this great library in couple of my projects which are using typescript. Now I'm bypassing ts errors with // @ts-ignore flag but it would be great to typings in this project.

Cannot use namespace 'Script' as a type.

When I build I see:

src/amphtml/amphtml.tsx:36420:54 - error TS2709: Cannot use namespace 'Script' as a type.

36420   version: PropTypes.string as PropTypes.Requireable<Script["version"]>,

[Question] Just use this library as a reference to Amp with Next.js and not adding the SSR methodology that the ampreact shows.

I'm just using react-amphtml to transform all the tags that amp has to Components. I'm not implementing the logic that the ampreact example has. In that case, I'm using the config that with-styled-components has. More specifically, like this:

import Document, {
  DocumentContext,
  Html,
  Head,
  Main,
  NextScript
} from "next/document";
import { ServerStyleSheet } from "styled-components";

export default class MyDocument extends Document {
  static async getInitialProps(ctx: DocumentContext) {
    const sheet = new ServerStyleSheet();
    const originalRenderPage = ctx.renderPage;

    try {
      ctx.renderPage = () =>
        originalRenderPage({
          enhanceApp: App => props => sheet.collectStyles(<App {...props} />)
        });

      const initialProps = await Document.getInitialProps(ctx);
      return {
        ...initialProps,
        styles: (
          <>
            {initialProps.styles}
            {sheet.getStyleElement()}
          </>
        )
      };
    } finally {
      sheet.seal();
    }
  }

  render() {
    return (
      <Html>
        <Head />
        <body>
          <Main />
          <NextScript />
        </body>
      </Html>
    );
  }
}

So, my question is, I'm just using react-amphtml to use the amp tags as components, something like this:

import React from "react";
import styled from "styled-components";
import * as Amp from "react-amphtml";

const NavBar = styled.nav`
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 1.5em 2em;
  position: sticky;
  z-index: 1;
`;

const MenuIcon = styled(Amp.AmpImg)`
  &:hover {
    cursor: pointer;
  }

  @media (min-width: 768px) {
    display: none;
  }
`;

export const Layout = ({ children }) => {
  return (
    <>
      <NavBar>
        <Amp.AmpImg
          specName="default"
          alt="logo"
          width={60}
          height={30}
          src="/Icons/Diey_Logo.svg"
        />
        <MenuIcon
          specName="default"
          alt="logo"
          width={30}
          height={30}
          src="/Icons/menu.svg"
        />
      </NavBar>
      {children}
    </>
  );
};

Believing that Next.js will care all about SSR with AMP. Is this a good practice?

amp-mustache

The extension 'amp-mustache' is referenced at version '0.1' which is a deprecated version. Please use a more recent version of this extension. This may become an error in the future.

Amp.AmpState not rendering

Hi there, I hope I am just missing something but I attempted to use your Amp.AmpState helper and found that it wasn't rendering anything in my final HTML. As far as I can tell, I am writing the code as described in the documentation.

import * as React from 'react';
import styled from "styled-components";
import * as Amp from 'react-amphtml';
import * as AmpHelpers from 'react-amphtml/helpers';

// ...

export default (props: Props) => {

       // ... 

	return (
		<AudioWrapper> //Styled component inside a larger Amp document 
			<Amp.AmpState id="myState">
			{{
				"content": 'collapsed',
			}}
			</Amp.AmpState>
		<div className="audio-player">
                // ... 

This may be due to your issue facebook/react#12568 as I am using React's renderToString, but I will note that AmpHelpers.Bind is outputting correctly (even if Storybook is stripping it out for some reason: storybookjs/storybook#3776).

For now I am going to try to use the target selector to achieve the functionality I need, but this may not be good enough down the road.

Typed components missing common element attributes

Hello,

in the example below, there is a tslint error when implementing component, saying that width and height props does not exist on the component...
so when generating the amphtml types in codegen, are these props intentionaly missing or there is a better workaround?

<AmpYoutube
    data-videoid={content![1]}
    width="960"
    height="540"
    i-amphtml-layout="responsive"
/>

Using AMpAnimation inside React

I am trying to use AmpAnimation inside a component. I am getting an error Cannot call a class as a function
TypeError: Cannot call a class as a function
at Object.classCallCheck (/node_modules/react-amphtml/dist/chunk1.js:14:11)
at AmpScripts (/node_modules/react-amphtml/dist/setup.js:16:17)
at processChild (/node_modules/react-dom/cjs/react-dom-server.node.development.js:2126:14) ....

find code below:

<Amp.AmpAnimation id="hideAnim" layout="nodisplay">
    <AmpSetup.AmpScripts type="application/json" >
      {hideAnim}
    </AmpSetup.AmpScripts>
  </Amp.AmpAnimation >;

const hideAnim = {
  "fill": "both"
  "duration": "200ms",
  "iterations": "1",
  "direction": "alternate",
  "animations": [
    {
      "selector": "#download-button",
      "keyframes": [
        { "opacity": "0", "visibility": "hidden" }
      ]
    }
  ]
};

is there a proper way ro use animation?

Rendering Amp.Sidebar to body tag

Currently in my react SSR application, i tried using AMP.sidebar which renders the Sidebar inside the react root component ("div" tag) rather than rendering as direct child of body Tag. Anyway work around to fix this?

React 17 ?

Hello,

thanks for this lib.
Any plans on supporting react 17 ?

Validation error in Amp Video

Hi,

thanks for this package, it works very well!
I'm getting a validation error that comes from amp video component:

The tag 'amp-video' requires including the 'amp-video' extension JavaScript. (see https://amp.dev/documentation/components/amp-video/)

Apparently amp validator is expecting to get:
<script async custom-element="amp-video" src="https://cdn.ampproject.org/v0/amp-video-0.1.js"></script>

But script below is the one injected in my document <head>
<script async="" custom-element="amp-video" data-script="amp-video" i-amphtml-inserted="" crossorigin="anonymous" src="https://cdn.ampproject.org/rtv/012107170150000/v0/amp-video-0.1.js"></script>

Video works fine, the only issue is referred to validation. Is there anything I can do to fix that?

Thanks!

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.