Coder Social home page Coder Social logo

nicolassiver / nodebb-plugin-ns-awards Goto Github PK

View Code? Open in Web Editor NEW
30.0 30.0 24.0 3.03 MB

A system for rewarding forum users. The plugin allows admin to define set of awards that could be granted to users for special accomplishments.

Home Page: https://community.nodebb.org/topic/4397/nodebb-plugin-ns-awards-ns-awards-give-medals

License: MIT License

JavaScript 84.31% Smarty 1.17% CSS 7.28% SCSS 7.24%
awards nodebb plugin profile

nodebb-plugin-ns-awards's People

Contributors

barisusakli avatar dependabot[bot] avatar julianlam avatar manv avatar nicolassiver 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

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

nodebb-plugin-ns-awards's Issues

awards_topic template is empty

NodeBB Version: v1.13.4-5

Issue:

I followed README and insert this line into post.tpl file

	<!-- IMPORT partials/awards_topic.tpl -->

The topic page has only an empty <div> element with class "ns-awards-topic", event though posts[n].nsRewards has items inside.

Fix:

Modify awards_topic.tpl file:
<!-- BEGIN nsRewards --> --> <!-- BEGIN posts.nsRewards --> & <!-- END nsRewards --> -> <!-- END posts.nsRewards -->
The original code may be valid for old version of benchpressjs?

<!-- IF posts.nsRewards.length -->
<div class="ns-awards-topic">
    <!-- BEGIN posts.nsRewards -->
    <div class="ns-awards-topic__item">
        <img class="ns-awards-topic__image teaser-pic img-responsive" src="{posts.nsRewards.award.url}" alt="{posts.nsRewards.award.name}" title="{posts.nsRewards.award.name}"
             data-toggle="awards-tooltip" data-placement="top" data-original-title="{posts.nsRewards.award.name}" />
    </div>
    <!-- END posts.nsRewards -->
</div>
<!-- ENDIF posts.nsRewards.length -->

Error on creating a new award

Error did occur: {"errno":-2,"code":"ENOENT","syscall":"copyfile","path":"/run/nodebb/node_modules/nodebb-plugin-ns-awards/public/uploads/award-dcc3c7ac-1659-42d0-a988-9ab0cab7db46.jpg","dest":"/app/code/public/uploads/awards/award-dcc3c7ac-1659-42d0-a988-9ab0cab7db46.jpg"}

image

Can't upload Awards Picture

Hi,

I am using NodeBB 0.9.3 and nodebb-plugin-ns-awards 2.1.0, I am hosting the forum on a subfolder, my url looks like this: https://example.com/forum/.

The ACP works, however when I try to upload a picture for the award It gets 404'ed.
POST https://example.com/api/admin/plugins/awards/images 404 (Not Found)

It posts to the wrong URL, or atleast that is what I think. I tried changing it in the plugin/index.js using both the pluginUri and apiUri, both with no result.

Is this because of the way the forum is set up using a subfolder? Or is it because it doesn't support it?
I think the problem is on my behalf and not a problem with the plugin.

Some times the management does not show rewards even if the reward is given

As you can see below,

image

admin has given award to this user and even his awards show on /awards page, but in ACP when i type this user, it says no award given to this user.

i have tested this with multiple users and awards, still same issue.

As you can see in log this user has been awarded before but it does not show in ACP management:
image

Cant Create a Award

Its write

Error did occur: {"errno":-2,"code":"ENOENT","syscall":"copyfile","path":"/var/www/nodebb/node_modules/nodebb-plugin-ns-awards/public/uploads/award-418ad325-fefc-40c3-b0bb-17cf606ccc29.png","dest":"/var/www/nodebb/public/uploads/awards/award-418ad325-fefc-40c3-b0bb-17cf606ccc29.png"}

Error after upgrading to 1.8.2

Apr 07 12:27:54 ip-172-30-3-69.ec2.internal nodebb[25913]: 2018-04-07T12:27:54.136Z [15335] - error:  TypeError: Cannot read property 'uid' of undefined
Apr 07 12:27:54 ip-172-30-3-69.ec2.internal nodebb[25913]: at /tank/nodebb/node_modules/nodebb-plugin-ns-awards/plugin/controller.js:326:54
Apr 07 12:27:54 ip-172-30-3-69.ec2.internal nodebb[25913]: at /tank/nodebb/node_modules/async/dist/async.js:1121:9
Apr 07 12:27:54 ip-172-30-3-69.ec2.internal nodebb[25913]: at eachOfArrayLike (/tank/nodebb/node_modules/async/dist/async.js:1055:9)
Apr 07 12:27:54 ip-172-30-3-69.ec2.internal nodebb[25913]: at eachOf (/tank/nodebb/node_modules/async/dist/async.js:1103:5)
Apr 07 12:27:54 ip-172-30-3-69.ec2.internal nodebb[25913]: at _asyncMap (/tank/nodebb/node_modules/async/dist/async.js:1119:5)
Apr 07 12:27:54 ip-172-30-3-69.ec2.internal nodebb[25913]: at Object.map (/tank/nodebb/node_modules/async/dist/async.js:1108:16)
Apr 07 12:27:54 ip-172-30-3-69.ec2.internal nodebb[25913]: at /tank/nodebb/node_modules/nodebb-plugin-ns-awards/plugin/controller.js:325:27
Apr 07 12:27:54 ip-172-30-3-69.ec2.internal nodebb[25913]: at nextTask (/tank/nodebb/node_modules/async/dist/async.js:5310:14)
Apr 07 12:27:54 ip-172-30-3-69.ec2.internal nodebb[25913]: at next (/tank/nodebb/node_modules/async/dist/async.js:5317:9)
Apr 07 12:27:54 ip-172-30-3-69.ec2.internal nodebb[25913]: at /tank/nodebb/node_modules/async/dist/async.js:958:16
Apr 07 12:27:54 ip-172-30-3-69.ec2.internal nodebb[25913]: at Settings.get (/tank/nodebb/node_modules/nodebb-plugin-ns-awards/plugin/settings.js:60:16)
Apr 07 12:27:54 ip-172-30-3-69.ec2.internal nodebb[25913]: at /tank/nodebb/node_modules/async/dist/async.js:66:19
Apr 07 12:27:54 ip-172-30-3-69.ec2.internal nodebb[25913]: at nextTask (/tank/nodebb/node_modules/async/dist/async.js:5310:14)
Apr 07 12:27:54 ip-172-30-3-69.ec2.internal nodebb[25913]: at Object.waterfall (/tank/nodebb/node_modules/async/dist/async.js:5320:5)
Apr 07 12:27:54 ip-172-30-3-69.ec2.internal nodebb[25913]: at Object.Controller.getPostsWithRewards (/tank/nodebb/node_modules/nodebb-plugin-ns-awards/plugin/controller.js:318:15)
Apr 07 12:27:54 ip-172-30-3-69.ec2.internal nodebb[25913]: at Object.Filter.getPosts [as method] (/tank/nodebb/node_modules/nodebb-plugin-ns-awards/plugin/filters.js:52:20)
Apr 07 12:27:54 ip-172-30-3-69.ec2.internal nodebb[25913]: 2018-04-07T12:27:54.137Z [15335] - info: [app] Shutdown (SIGTERM/SIGINT) Initialised.
Apr 07 12:27:54 ip-172-30-3-69.ec2.internal nodebb[25913]: [cluster] Child Process (15329) has exited (code: 1, signal: null)

error opening /user/:userslug page on v2.8.1

on v2.8.1, when opening my own user profile:
image

2023-01-13T18:25:30.091Z [4567/89082] - error: GET /user/admin
TypeError: Cannot read properties of undefined (reading 'uid')
    at /home/frozen_byte/Projects/nodebb-plugin-ns-awards/plugin/controller.js:193:54
    at nextTask (/home/frozen_byte/Projects/nodebb-plugin-ns-awards/node_modules/async/dist/async.js:5759:13)
    at next (/home/frozen_byte/Projects/nodebb-plugin-ns-awards/node_modules/async/dist/async.js:5767:13)
    at /home/frozen_byte/Projects/nodebb-plugin-ns-awards/node_modules/async/dist/async.js:327:20
    at Settings.get (/home/frozen_byte/Projects/nodebb-plugin-ns-awards/plugin/settings.js:60:16)
    at /home/frozen_byte/Projects/nodebb-plugin-ns-awards/node_modules/async/dist/async.js:53:33
    at nextTask (/home/frozen_byte/Projects/nodebb-plugin-ns-awards/node_modules/async/dist/async.js:5759:13)
    at Object.waterfall (/home/frozen_byte/Projects/nodebb-plugin-ns-awards/node_modules/async/dist/async.js:5770:9)
    at Object.awaitable (/home/frozen_byte/Projects/nodebb-plugin-ns-awards/node_modules/async/dist/async.js:211:32)
    at Object.Controller.getAccountWithRewards (/home/frozen_byte/Projects/nodebb-plugin-ns-awards/plugin/controller.js:186:15)

Ability for other users to give other users rewards as well

I was just wondering this is a great plugin but right now I see a restriction that only admin can give them badges to the other uses since admin is probably one and it has limited creativity and number of good rewards to give...

I was just thinking if other users can start giving rewards to their friends or followers on the phone then that would be awesome and because other users can define any name of the reward.. so they don't have necessarily to be pre define every time by admin...

Rewards can be named anything by other users.

Can we add this thing in this plugin so that it also has admin rewards and also the user rewards

Allow the tooltip to show when tap on award icon on profile or topic view

This is just an enhancement feature:

On mobile users don't know what each award title is by just looking at the icon, and the tool tip on mobile does not show. it should show on profile and post view if user taps on icon on mobile.

and i also think tapping the award icon should take users to /awards page

0.9.3 Hook `filter:user.delete` is deprecated, please use an alternative

Hey there,

When the ns-awards is installed and activated, I receive this warning on a restart:

[2:08:47 pm] 10/1 14:08 [24362] - warn: [plugins/nodebb-plugin-ns-awards] Hook filter:user.delete is deprecated, please use an alternative

And deleting a user will crash our forums on a mongodb type error "callback is not a function".
When uninstalling the plugin the issue is resolved.

Our nodebb version is 0.9.3

crash on latest nodebb

TypeError: Cannot read properties of null (reading 'maxRewardsPerPost')
    at /home/saas/nodebb/node_modules/nodebb-plugin-ns-awards/plugin/controller.js:320:30

auto-complete component make user who has a short name(length<3) can't get awards

the problem is caused by these code

client/acp/components/Autocomplete.react.js

 _validateInput: function () {
        if (this.state.inputText.length >= 3) {
            this.props.valueDidChange(this.state.inputText);
        }
    }

I understand that userName.length>3 is common in english world. But in other language (such as chinese) is not that common.

do you need me to make a PR to fix this?

Feature request: Make API accessible from 3rd party application

There are 2 API endpoints accessible from server side hooks:

  • filter:ns.awards.getAwards
  • static:ns.awards.rewardUser

It would be great to make these endpoints accessible from 3rd party application using URLs. There is a great plugin nodebb-plugin-write-api which provides this functionality via its hook (https://github.com/NodeBB/nodebb-plugin-write-api/blob/master/routes/v2/index.js#L44-L58).

So everything what is need to do is to create URLs for awards endpoints:

{
    bindRoutes: function(params, callback) {
        var router = params.router;
        var apiMiddleware = params.apiMiddleware;

        router.post(
            '/plugins/ns-awards/get-awards',
            apiMiddleware.requireUser,
            function(req, res) {
                api.getAwards(
                    req.body,
                    function(_, payload) {
                        res.send(payload);
                    }
                )
            }
        );

        router.post(
            '/plugins/ns-awards/reward-user',
            apiMiddleware.requireUser,
            function(req, res) {
                api.rewardUser(
                    req.body,
                    function(_, payload) {
                        res.send(payload);
                    }
                )
            }
        );

        callback(null, {
            router: router
        });
    },
},

and registr the method to nodebb-plugin-write-api using plugin.json

{
    "hook": "filter:plugin.write-api.routes",
    "method": "hooks.writeApi.bindRoutes"
}

Pros:

  • nodebb-plugin-write-api has already secured its API using baerer token (but it is not in conflict with awards security - it can be double secured)
  • API endpoints are accessible via /api/v2/plugins/ns-awards/get-awards and /api/v2/plugins/ns-awards/reward-user
  • in case any user does not have the nodebb-plugin-write-api plugin, nothing changed and everything works

Can I make pull request? Are you OK with adding this functionality?

Where i need to put the template codes?

I put the in /node_modules/nodebb-theme-persona/templates/partials/topic/post.tpl after the line for . But its CSS are not correct when i reloaded the forum. Its overlapping with some content of the topic and the label showing the time of the topic is misaligned due to it? Where do i need to add the code to work without changing anything else?

Awards on profile pages are only showing for 1 user and not others, and best dimensions for images?

I have followed your exact steps to add the partial to profile.tpl, but for some reason only awards are being shown for this user profile

https://chatrooms.talkwithstranger.com/user/willow

but as u can see other users also have awards but they are not rendering on their profile view

https://chatrooms.talkwithstranger.com/awards

e.g this user https://chatrooms.talkwithstranger.com/user/layla

Also, what should be the exact dimensions for the awards images so that they appear 100% responsive and perfect on all screens on topic view ,profile view and awards view, in our case it seems distorted, see please

image

Error after upgrading to 1.11.1

Command failed: npm install [email protected] --save npm WARN checkPermissions Missing write access to /home/admin/lippi-dingtalk-club/target/lippi-dingtalk-club/node_modules/winston/node_modules/colors npm ERR! path /home/admin/lippi-dingtalk-club/target/lippi-dingtalk-club/node_modules/winston/node_modules/colors npm ERR! code ENOENT npm ERR! errno -2 npm ERR! syscall access npm ERR! enoent ENOENT: no such file or directory, access '/home/admin/lippi-dingtalk-club/target/lippi-dingtalk-club/node_modules/winston/node_modules/colors' npm ERR! enoent This is related to npm not being able to find a file. npm ERR! enoent npm ERR! A complete log of this run can be found in: npm ERR! /home/admin/.npm/_logs/2018-12-20T11_33_29_387Z-debug.log

Internal Error

Hi,

I'm trying to use nodebb-plugin-ns-awards but after installing and restarting nodebb.

I get this error when going to "awards" in plugins view at the admin panel:

Internal Error.
Oops! Looks like something went wrong!
/admin/plugins/awards
Failed to lookup view "admin/plugins/awards" in views directory "/home/x/Ensemble/build/public/templates"

I have the latest version of nodebb installed.

edit: just had to rebuild nodebb to solve

Error when uploading Images for Awards

Hi there, I am running into this isssue when I am trying to create an award.

Error did occur: {"errno":-2,"code":"ENOENT","syscall":"copyfile","path":"/var/www/nodebb/node_modules/nodebb-plugin-ns-awards/public/uploads/award-467905ec-46c8-4643-85eb-69bfb01e5b62.png","dest":"/var/www/nodebb/public/uploads/awards/award-467905ec-46c8-4643-85eb-69bfb01e5b62.png"}

It might be something wrong with my VPS setup, however I am not sure how to solve it and figured I should ask for some assistance.

Callback is not a function on nodebb v1.13.0

Hi, when calling the plugin admin page on nodebb v1.13.0 the following error occurs:

nodebb_1                   | 2019-12-01T16:39:17.486Z [4567/151] - error: uncaughtException: callback is not a function
nodebb_1                   | TypeError: callback is not a function
nodebb_1                   |     at /opt/nodebb/node_modules/nodebb-plugin-ns-awards/plugin/sockets.js:91:13
nodebb_1                   |     at /opt/nodebb/node_modules/nodebb-plugin-ns-awards/node_modules/async/dist/async.js:473:16
nodebb_1                   |     at next (/opt/nodebb/node_modules/nodebb-plugin-ns-awards/node_modules/async/dist/async.js:5329:29)
nodebb_1                   |     at /opt/nodebb/node_modules/nodebb-plugin-ns-awards/node_modules/async/dist/async.js:969:16
nodebb_1                   |     at /opt/nodebb/node_modules/nodebb-plugin-ns-awards/node_modules/async/dist/async.js:1140:9
nodebb_1                   |     at /opt/nodebb/node_modules/nodebb-plugin-ns-awards/node_modules/async/dist/async.js:473:16
nodebb_1                   |     at iteratorCallback (/opt/nodebb/node_modules/nodebb-plugin-ns-awards/node_modules/async/dist/async.js:1064:13)
nodebb_1                   |     at /opt/nodebb/node_modules/nodebb-plugin-ns-awards/node_modules/async/dist/async.js:969:16
nodebb_1                   |     at /opt/nodebb/node_modules/nodebb-plugin-ns-awards/node_modules/async/dist/async.js:1137:13
nodebb_1                   |     at /opt/nodebb/node_modules/nodebb-plugin-ns-awards/plugin/controller.js:250:25 {"error":{},"stack":"TypeError: callback is not a function\n    at /opt/nodebb/node_modules/nodebb-plugin-ns-awards/plugin/sockets.js:91:13\n    at /opt/nodebb/node_modules/nodebb-plugin-ns-awards/node_modules/async/dist/async.js:473:16\n    at next (/opt/nodebb/node_modules/nodebb-plugin-ns-awards/node_modules/async/dist/async.js:5329:29)\n    at /opt/nodebb/node_modules/nodebb-plugin-ns-awards/node_modules/async/dist/async.js:969:16\n    at /opt/nodebb/node_modules/nodebb-plugin-ns-awards/node_modules/async/dist/async.js:1140:9\n    at /opt/nodebb/node_modules/nodebb-plugin-ns-awards/node_modules/async/dist/async.js:473:16\n    at iteratorCallback (/opt/nodebb/node_modules/nodebb-plugin-ns-awards/node_modules/async/dist/async.js:1064:13)\n    at /opt/nodebb/node_modules/nodebb-plugin-ns-awards/node_modules/async/dist/async.js:969:16\n    at /opt/nodebb/node_modules/nodebb-plugin-ns-awards/node_modules/async/dist/async.js:1137:13\n    at /opt/nodebb/node_modules/nodebb-plugin-ns-awards/plugin/controller.js:250:25","exception":true,"date":"Sun Dec 01 2019 16:39:17 GMT+0000 (UTC)","process":{"pid":151,"uid":0,"gid":0,"cwd":"/opt/nodebb","execPath":"/usr/local/bin/node","version":"v8.16.2","argv":["/usr/local/bin/node","/opt/nodebb/app.js"],"memoryUsage":{"rss":152141824,"heapTotal":122081280,"heapUsed":108288944,"external":36438704}},"os":{"loadavg":[0.08642578125,0.5107421875,0.47998046875],"uptime":28325},"trace":[{"column":13,"file":"/opt/nodebb/node_modules/nodebb-plugin-ns-awards/plugin/sockets.js","function":null,"line":91,"method":null,"native":false},{"column":16,"file":"/opt/nodebb/node_modules/nodebb-plugin-ns-awards/node_modules/async/dist/async.js","function":null,"line":473,"method":null,"native":false},{"column":29,"file":"/opt/nodebb/node_modules/nodebb-plugin-ns-awards/node_modules/async/dist/async.js","function":"next","line":5329,"method":null,"native":false},{"column":16,"file":"/opt/nodebb/node_modules/nodebb-plugin-ns-awards/node_modules/async/dist/async.js","function":null,"line":969,"method":null,"native":false},{"column":9,"file":"/opt/nodebb/node_modules/nodebb-plugin-ns-awards/node_modules/async/dist/async.js","function":null,"line":1140,"method":null,"native":false},{"column":16,"file":"/opt/nodebb/node_modules/nodebb-plugin-ns-awards/node_modules/async/dist/async.js","function":null,"line":473,"method":null,"native":false},{"column":13,"file":"/opt/nodebb/node_modules/nodebb-plugin-ns-awards/node_modules/async/dist/async.js","function":"iteratorCallback","line":1064,"method":null,"native":false},{"column":16,"file":"/opt/nodebb/node_modules/nodebb-plugin-ns-awards/node_modules/async/dist/async.js","function":null,"line":969,"method":null,"native":false},{"column":13,"file":"/opt/nodebb/node_modules/nodebb-plugin-ns-awards/node_modules/async/dist/async.js","function":null,"line":1137,"method":null,"native":false},{"column":25,"file":"/opt/nodebb/node_modules/nodebb-plugin-ns-awards/plugin/controller.js","function":null,"line":250,"method":null,"native":false}]}
nodebb_1                   | 2019-12-01T16:39:17.487Z [4567/151] - error: callback is not a function
nodebb_1                   | 2019-12-01T16:39:17.488Z [4567/151] - info: [app] Shutdown (SIGTERM/SIGINT) Initialised.

nodebb 0.9.2 - crash report

error: TypeError: Cannot read property 'uid' of undefined
at /.../nodebb-plugin-ns-awards/plugin/controller.js:186:54
at /.../node_modules/async/lib/async.js:356:13
at async.forEachOf.async.eachOf (/home/nodeBB/forum/node_modules/async/lib/async.js:233:13)
at _asyncMap (/.../node_modules/async/lib/async.js:355:9)
at Object.map (..../node_modules/async/lib/async.js:337:20)
at /.../node_modules/nodebb-plugin-ns-awards/plugin/controller.js:184:27
at fn (/..../node_modules/async/lib/async.js:741:34)
at /..../node_modules/async/lib/async.js:1208:16
at ..../node_modules/async/lib/async.js:166:37
at /..../node_modules/async/lib/async.js:701:43

Nodebb 1.11.1 crashes

TypeError: Cannot read property 'uid' of null
    at /var/www/nodebb/node_modules/nodebb-plugin-ns-awards/plugin/controller.js:324:55
    at /var/www/nodebb/node_modules/async/dist/async.js:1135:9
    at eachOfArrayLike (/var/www/nodebb/node_modules/async/dist/async.js:1069:9)
    at eachOf (/var/www/nodebb/node_modules/async/dist/async.js:1117:5)
    at _asyncMap (/var/www/nodebb/node_modules/async/dist/async.js:1133:5)
    at Object.map (/var/www/nodebb/node_modules/async/dist/async.js:1122:16)
    at /var/www/nodebb/node_modules/nodebb-plugin-ns-awards/plugin/controller.js:323:27
    at nextTask (/var/www/nodebb/node_modules/async/dist/async.js:5324:14)
    at next (/var/www/nodebb/node_modules/async/dist/async.js:5331:9)
    at /var/www/nodebb/node_modules/async/dist/async.js:969:16
    at Settings.get (/var/www/nodebb/node_modules/nodebb-plugin-ns-awards/plugin/settings.js:60:16)
    at /var/www/nodebb/node_modules/async/dist/async.js:66:19
    at nextTask (/var/www/nodebb/node_modules/async/dist/async.js:5324:14)
    at Object.waterfall (/var/www/nodebb/node_modules/async/dist/async.js:5334:5)
    at Object.Controller.getPostsWithRewards (/var/www/nodebb/node_modules/nodebb-plugin-ns-awards/plugin/controller.js:316:15)
    at Object.Filter.getPosts [as method] (/var/www/nodebb/node_modules/nodebb-plugin-ns-awards/plugin/filters.js:52:20)
2019-01-08T04:48:11.747Z [4567/12190] - �[32minfo�[39m: [app] Shutdown (SIGTERM/SIGINT) Initialised.

Nodebb Version 1.11.1
Plugin version 5.1.0

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.