Git Product home page Git Product logo

erpnet.fp's People

Contributors

de1facto avatar dilyanrusev avatar drjeckyll avatar g-vvv avatar i-argentinski avatar kostadinko avatar moxata avatar o-ivanov avatar p-kostov avatar rosen4o 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  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

erpnet.fp's Issues

Support for non-default operator and operatorPassword

Currently, only the default operator and password are passed to the fiscal printer for each printing job.

This is fine for factory default setup printers. However, the printers might have special setups for operators and passwords.

The solution is to support non-default "operator" and "operatorPassword" in the JSON body for all POST requests. This includes:
/receipt
/reversalreceipt
/deposit
/withdraw
/xreport
/zreport
/datetime

For example:

http://localhost:8001/printers/dt517985/deposit

BODY:

{
    "amount":12.34,
    "operator": "0001",
    "operatorPassword": "1234"
}

If "operator" or "operatorPassword" are not specified, the defaults should be used.

Return fiscal memory number on each printing of fiscal receipt

The user information system needs to record the "fiscal memory serial number" (FMSN) for each printing transaction.

Currently, the FMSN can be obtained by a call to GetPrinterInfo. However, we need to have transactional consistency and guarantee the FMSN to which each receipt is printed.

Desired change:
In the dataset, returned by PrintReceipt/PrintReversalReceipt, include the FMSN on which the receipt/reversal was printed.

Customization of fiscal bon

View of bon
Would be great if all settings of OpenFiscalBon are presented into input JSON. For example Tremol's OptionReceiptFormat and OptionPrintVAT, for Datecs TillNumber etc.

Often I print additional info for specific articles (as serial numbers, contract number etc.), so in my subsys I have PrintBefore and PrintAfter in Items object. Additionally in PrintBefore and PrintAfter sometimes I print barcodes too.

On error, result is "ok":true.

When message of type error exists, the print is canceled corectlly, but result "ok" is set to true.
Is not it expected to be false?

{
   "taskStatus":"finished",
   "result":{
      "receiptNumber":"",
      "receiptDateTime":"0001-01-01T00:00:00",
      "receiptAmount":0.0,
      "fiscalMemorySerialNumber":"02746009",
      "ok":true,
      "messages":[
         {
            "type":"error",
            "code":"E406",
            "text":"Payment type Check unsupported"
         },
         {
            "type":"info",
            "code":"",
            "text":"Error occured while printing receipt items"
         }
      ]
   }
}}

Show printer address in admin web UI

The idea is to display the full printer address in the admin UI. This will facilitate external applications, which require the users to configure the printer address.

The printer address should be displayed when we open the printer details in the admin UI.

For example, a printer address is:
https://mycomputer:8001/printers/dt1234

The "https://mycomputer:8001" part should be taken from the URL of the web request which requested the admin web UI.

For example, the user requested the admin UI with:
https://mycomputer:8001/admin

This means that he "sees" the print server as "https://mycomputer:8001". So, we will use this to construct the full printer address.

Server version in the log and console

This will allow better debugging, because we will have a reference to the version of the server that created the debug.log file and console output.

Create Admin panel with MQTT activation

The admin panel would allow remote administration (making changes to the config file, etc.) of the print server.

Currrently, the admin panel would be a web page. In the future, Api access should also be allowed.

All admin access (web page AND api access) should be secured with a simple "Admin Secret". The admin secret is a password, stored in the config file.

NOTE: If the admin password is NOT set, ALL admin access is DISABLED. E.g., there SHOULD be an admin password in order to access the admin part.

(1) Admin password
The password would be stored in the ErpNet.FP section, under the name "AdminPassword". It would be plain-text "secret" text.

NOTE: Obviously, this is not the highest level of security, but it is secure enough for remote access.

(2) MQTT secret
The MQTT secret is used to create topic names for the MQTT communication. It is stored in the config file, in the ErpNet.FP section, under the name "MqttSecret".

(3) Functions of the admin web page
Location: /admin/
Login: Each access of any admin page should require a login, requiring the user to type the admin password.
Functions:

  • Button "Set Admin Password" - should allow the user to change the admin password.
  • Button "Enable/Disable MQTT"
  • If there is no MqttSecret, a new one is generated
  • Upon MQTT activation (or just always), a JavaScript snippet should be displayed, showing the necessary JavaScript code to access the printing functions.
    NOTE: The snippet should be with the MQTT secret already integrated into it.

Selection of multi platform .Net Core serial port library

We must select multi platform .net core serial port library, which will be used as standard underlying communication with Fiscal Printers and Devices. This is team task, so I assigned this task to all of us. Please consider that there are not so many packed as NuGet packages, as well as we must select the library with minimal dependencies and maximum portability.
Without this library we will be forced to use only Microsoft Windows System.IO.Ports, which is not supported in .Net Core, and stick only with Windows :(

Include requests and responses in debug.log

In order to be better able to handle support requests in the future, the debug.log file should contain data about requests and responses. To be more precise - the full text of each request and each response should be dumped in debug.log.

The text representation should be clear of any escape symbols. The idea is that sometimes the problems with malformed requests are exactly bad escaping (for example, bad escaping of the double quotes (") in a JSON request).

Config should support specifying printers and auto detect

{
  "Logging": {
    "LogLevel": {
      "Default": "Warning"
    }
  },
  "Printers": {
    "prn1": { "Uri": "bg.zk.zfp.com://COM1" },
    "prn2": { "Uri": "bg.dt.p.isl.tcp://192.168.1.100:4999"  }
  },
  "AutoDetect": true,
  "Kestrel": {
    "EndPoints": { 
      "Http": {
        "Url": "http://0.0.0.0:8001"
      }
    }
  }
}

Unable to print receipts due to encoding issue

Describe the bug
Wrong encoding in the committed file: BgIslFiscalPrinter.cs - the file is saved with ANSI encoding which replaces the Cyrillic characters from the tax group with unreadable ones. This subsequently leads to the inability to process the POST request, returning a syntax error.
Please commit the file again with UTF-8 encoding.

Describe the device(s) you are using
Daisy Perfect S

How To Reproduce
Just check the content of the committed file:

switch (taxGroup) { case TaxGroup.TaxGroup1: return "À"; case TaxGroup.TaxGroup2: return "Á"; case TaxGroup.TaxGroup3: return "Â"; case TaxGroup.TaxGroup4: return "Ã"; case TaxGroup.TaxGroup5: return "Ä"; case TaxGroup.TaxGroup6: return "Å"; case TaxGroup.TaxGroup7: return "Æ"; case TaxGroup.TaxGroup8: return "Ç"; default: throw new StandardizedStatusMessageException($"Tax group {taxGroup} unsupported", "E411"); }

Expected behavior
Unable to print receipts.

Skip the "code" field in the return JSON when it has no value

Currently, messages/code is included in the return JSON even if it has no value.

For example:

{
	"ok": "false",
	"messages": [
		{ 
			"type": "error",
			"code": "E201",
			"text": "The fiscal memory is full"
		},
		{
			"type": "info",
			"code": "",
			"text": "Serial number and number of FM are set"
		},
		{
			"type": "info",
			"code": "",
			"text": "FM is formatted"
		}
	]
}

The "code" field for the 2nd and the 3rd messages is unnecessary and even wrong. The code really has no value. It is neither "" nor "null".

Just skip the code if it has no value.

The above JSON should become:

{
	"ok": "false",
	"messages": [
		{ 
			"type": "error",
			"code": "E201",
			"text": "The fiscal memory is full"
		},
		{
			"type": "info",
			"text": "Serial number and number of FM are set"
		},
		{
			"type": "info",
			"text": "FM is formatted"
		}
	]
}

Simplify the resource names

POST /printreceipt => POST /receipt
POST /printxxx => POST /xxx
...
POST /setdatetime => POST /datetime

The idea is that we drop the verb from the resource name. The HTTP verb is now the verb.

Implement Invoice, Credit and Debit notice functionality

First of all I am very grateful for the existence of this product and big congrats to all developers. The software is very useful.

Here is the future request I am thinking about:

Is your feature request related to a problem? Please describe.
A lot of companies print the invoice in the fiscal bon. For example Tehnomarket in Bulgaria.

Describe the solution you'd like
I would expect an API endpoints where a request can make the fiscal printer to output a fiscal bon with invoice, credit or debit notice details on it.

Describe alternatives you've considered
The only alternative is to print an invoice or the other types of documents standalone and attach the fiscal bon to the document.

Simplify result JSON formats

(1) ResultInfo
Used by:

  • /printers/xxx/reversalreceipt
  • /printers/xxx/deposit
  • /printers/xxx/withdraw
  • /printers/xxx/xreport
  • /printers/xxx/zreport
  • /printers/xxx/datetime

Fields ("ok" SHOULD be the first field):

  • ok: true/false
  • messages: Array Of:
    type: info / warning / error
    code - standard code of the message. null if there is no standard code for the message.
    text

Example:

{
  "ok": "false",
  "messages": [
    { 
      "type": "error",
      "code": "ERR03",
      "text": "The fiscal memory is full."
    },
    ...
  ]
}

(2) PrinterStatusResultInfo: ResultInfo
Used by:

  • /printers/xxx/status
  • /printers/xxx/datetime

Fields:

  • deviceDateTime (contains the word "device" to signify that this is the printer device time and not just the time of the PC, where the lib is running)

Example:

{
  "ok": "true",
  "messages": [
    { 
      "type": "warning",
      "code": "WRN02",
      "text": "Revenue agency reporting temporary problem."
    },
    ...
  ],
  "deviceDateTime": ...
}

(3) PrintReceiptResultInfo: ResultInfo
Used by:

  • /printers/xxx/receipt

Fields:

  • receiptNumber
  • receiptDateTime
  • receiptAmount
  • fiscalMemorySerialNumber

Example ("code" is not specified, because it is null for the included message):

{
  "ok": "true",
  "messages": [
    { 
      "type": "info"
      "text": "Device registers are set."
    },
    ...
  ],
  "receiptNumber": ...,
  "receiptDateTime": ...,
  "receiptAmount": ...,
  "fiscalMemorySerialNumber": ...
}

Cash amount and Timestamp in Info Method

A few recommendations
It's convenient to return in info method (which I use like an a ping or init) current cash because Cash Out, sometimes Storno, Operator Name change (of Datecs) and probably others will fail if application does not catch cash availability. Also current time of ECR will be valuable in info, so application can try to fix wrong calendar.
I found that devices fails if item price is zero (gift) and in my application I replace "Sell" method with a "print comment" if price is zero, but this behavior is constant and could be catch in the communication layer to avoid additional logic in application.
And last, because subtotal have to be positive in every moment some negative items should be shifted at the end if current amount goes negative.

Improve the console

Make the following changes to the console window:

(1) Use fixed-width font

(2) The default console window size should be able to show 80x25 characters.

(3) [BUG] The messages are shown on the same line - not CR & LF-ed to new line for each message.

(4) [OPTIONAL] Support setting "Console Verbosity Level" in the tray menu.
Possible levels:

  • Minimal - Only Show Warnings/Errors
  • Normal - Show Normal Messages (DEFAULT)
  • Debug - Maximum Verbosity

The "Normal" level (or whatever it is called) should include "Found 3 printers" and similar messages. The idea is that, by default, we can see the detected/configured printers in the default console.

NOTE: Changing the verbosity level should be saved to the config and applied to the running instance immediately.

Admin controller a.k.a. /admin

Admin controller will provide feedback and control abilities for third party apps over ErpNet.FP, via Kestrel http. ErpNet.FP.Win.Manager for example will use it for feedback and control over ErpNet.FP.Win.

DATECS FP-800 over tcp failed

Hi.
I have problem connecting to datecs fp-800 printer over tcp.

This is the console log.

info: ErpNet.FP.Server.Program[0]
Starting the service...
info: ErpNet.FP.Server.Contexts.PrintersControllerContext[0]
Detecting configured printers...
info: ErpNet.FP.Server.Contexts.PrintersControllerContext[0]
Trying dt315421: bg.dt.p.isl.com://COM1, OK
info: ErpNet.FP.Server.Contexts.PrintersControllerContext[0]
Trying dt315421_1: bg.dt.p.isl.tcp://192.168.1.94, failed
info: ErpNet.FP.Server.Contexts.PrintersControllerContext[0]
Detecting done. Found 1 available printer(s).
Hosting environment: Production
Content root path: c:\Users\loboda\Downloads\win-x64
infoNow listening on: http://0.0.0.0:8001
Application started. Press Ctrl+C to shut down.
: ErpNet.FP.Server.Services.KeepAliveHostedService[0]
Keep Alive Background Service is starting.
info: ErpNet.FP.Server.Services.KeepAliveHostedService[0]
Keep Alive Background Service running...
info: ErpNet.FP.Server.Services.KeepAliveHostedService[0]
Keep Alive Background Service done.
info: ErpNet.FP.Server.Services.KeepAliveHostedService[0]
Keep Alive Background Service running...
info: ErpNet.FP.Server.Services.KeepAliveHostedService[0]
Keep Alive Background Service done.
info: ErpNet.FP.Server.Services.KeepAliveHostedService[0]
Keep Alive Background Service running...
info: ErpNet.FP.Server.Services.KeepAliveHostedService[0]
Keep Alive Background Service done.
info: ErpNet.FP.Server.Services.KeepAliveHostedService[0]
Keep Alive Background Service running...
info: ErpNet.FP.Server.Services.KeepAliveHostedService[0]
Keep Alive Background Service done.

No problem when using com1 port.

No problem using other software with the fiscal printer (not at the same time) so no network problem.

this is my appsettings.json

{
"Logging": {
"LogLevel": {
"Default": "Information"
}
},
"ErpNet.FP": {
"AutoDetect": false,
"ServerId": "aR5rIm76EESRhUmxVqTLjA",
"Printers": {
"dt315421": {
"Uri": "bg.dt.p.isl.com://COM1"
},
"dt315421_1": {
"Uri": "bg.dt.p.isl.tcp://192.168.1.94"
}
}
},
"Kestrel": {
"EndPoints": {
"Http": {
"Url": "http://0.0.0.0:8001"
}
},
"Limits": {
"MaxConcurrentConnections": 100,
"MaxConcurrentUpgradedConnections": 100,
"MaxRequestBodySize": 20480,
"MaxRequestHeaderCount": 50
}
}
}

I hear the beep of tcp connection but the status is failed.

I am attaching wireshark capture file of the transmitted packets.

fp800.zip

"discount-amount" error on protocol bg.dt.c.isl.com

Describe the bug
Syntax error while print "discount-amount" on protocol bg.dt.c.isl.com
Seems wrong prefix "$" before the amount. The protocol reference points ";"

Executed command:
Request(31): 'Артикул Б1.00*1$-0.03'

Protocol refence:
31h (49) [<L1>][<Lf><L2>]<Tab><TaxCd><[Sign]Price>[*<Qwan>][,Perc|;Abs]

Describe the device(s) you are using
Datecs DP-150

Screenshots

Request(31): 'Артикул	Б1.00*1$-0.03'
>>>1 39 29 31 C0 F0 F2 E8 EA F3 EB 9 C1 31 2E 30 30 2A 31 24 2D 30 2E 30 33 5 30 39 3E 30 3 
<<<16 
<<<1 2B 29 31 4 A1 A0 88 80 84 82 5 30 33 3D 3D 3 

Support async printing and queueing

The idea is that each printing request will be enqueued in a queue.

(1) /printreceipt
will:

  • enqueue the printing task.
  • wait up to 29 secs for the queued task.
  • return the usual PrintInfo result

(2) /printreceipt?asynctimeout=15000
will:

  • enqueue the printing task.
  • wait up to 15000 ms.
  • If the print task is finished within 15000 ms - return the usual PrintInfo result
  • if the print job took more than 15000 ms - return TaskId result.

(3) /printreceipt?asynctimeout=0
will:

  • enqueue the printing task.
  • return TaskId result.

Keep printer time synced with NTP

Keep the printer synchronized with EU NTP time server.

The service should regularly check (or on each PrintReceipt) NTP server and if the printer current time is out of sync - set it.

If the difference between the NTP and the FP is more than 30 sec - then set the printer time.

The NTP server pool should default to some EU NTP server pool. But the address of the NTP server should be configurable through the config file.

Support /xreport

The fiscal printers support both "xreport" and "zreport". The FP library already supports "zreport". The current task is to make support for "xreport".

(1) Support POST /xreport
(2) Rename "/zeroingreport" to just "/zreport"

Print X/Z report from admin page

The idea is to facilitate the users/developers. The applications will no longer need to integrate functionality for printing X/Z reports. This will be doable from within the print server web interface.

From within the admin web page, put
Print X Report
Print Z Report
buttons.

These button should initiate the printing of X and Z reports.

Retain COM port open

ErpNet Retains COM port open although there is no printer
After autodection phase ErpNet continue without close serial port that no printer detected.

POS terminals, scales or other hardware on this ports will not to work
If we have POS terminals, scales or other hardware that communicating occasionally they will fail on next try, because port is already opened.

I am not a C# master but suggest fixing in Transport.cs -> ComTransport.cs

        public override void CloseChannel(string address)
        {
            if (openedChannels.TryGetValue(address, out Channel? channel))
            {
                channel.Dispose();
                openedChannels.Remove(address);
            }
        }

and in Provider.cs after drivers iteration try:

                    if (!Found)
                    {
                        transport.CloseChannel(availableAddress.address); 
                    }

That fix is working for me.

DP-150

Hi,
I'm trying to test with Datecs DP-150 but it can not be detected.
FPInit detects it and test fiscal receipts can be printed, so it is correctly attached/setup.
Can you please help out.
Thanks

E403 - priceModifierValue - should be positive number.

Testing with the following curl command results an error - i dont have "priceModifierValue" in my command.

curl --location --request POST "http://192.168.1.149:8001/printers/tcp/receipt" \
  --header "Content-Type: application/json" \
  --data "{
	\"uniqueSaleNumber\": \"DT279013-DD01-0000001\",
	\"items\" : 
	[
		{
			\"text\": \"Cheese\",
			\"quantity\": 1,
			\"unitPrice\": 12,
			\"taxGroup\": 2
		}
	]
}"

the result is

"ok": false,
	"messages": [{
		"type": "error",
		"code": "E403",
		"text": "Item 1: \"priceModifierValue\" should be positive number. You can avoid setting priceModifier if you do not want price modification"
	}, {
		"type": "error",
		"code": "E403",
		"text": "Item 1: \"priceModifierValue\" should'nt be \"none\" or empty. You can avoid setting priceModifier if you do not want price modification"

Using version - ver.1.0.2006.1330

Payment error on async mode cause infinitely running task


name: Bug report
about: Create a report to help us improve
title: 'Payment error on async mode cause infinitely running task'
labels: bug
assignees: ''


Describe the bug
When try print error receipt, print stopping before payment row and task stay "running" infinitely. The printing stuck to items row.
When try print non error receipt after, his task receive status finished and finalize stucked printing with cancelation. But the first receipt task continue return "running" infinity.

The same receipt with payment "check" in synchronous mode is finalized correctly.

Describe the device(s) you are using
Datecs DP-150 in non-fiscal mode
{"uri":"bg.dt.c.isl.com://COM7","serialNumber":"DT746009","fiscalMemorySerialNumber":"02746009","company":"Datecs","model":"DP-150","firmwareVersion":"265403 08Nov18 1050","itemTextMaxLength":22,"commentTextMaxLength":42,"operatorPasswordMaxLength":8}

How To Reproduce

  1. Print receipt with payment "check", to force error E404 not allowed in current mode.
  2. Task state stay "running" for 30 minutes and continue. The receipt stuck printed to items rows.
  3. Print another receipt with payment "cash"
  4. The second receipt task_id return status finished, with error E404. The printer finalize stucked print with cancelation.
  5. Task first receipt task continue to return "running"
    Steps are visible in attached debug.log

Expected behavior
In step 2. task should return state finished with error E404.

Screenshots
20190602_143031
debug.log.1.zip

Additional context

Support configurable logging

{
  "Logging": {
    "LogLevel": {
      "Default": "Warning"
    }
  },
  "Printers": {
    "prn1": { "Uri": "bg.zk.zfp.com://COM1" },
    "prn2": { "Uri": "bg.dt.p.isl.tcp://192.168.1.100:4999"  }
  },
  "AutoDetect": true,
  "Kestrel": {
    "EndPoints": { 
      "Http": {
        "Url": "http://0.0.0.0:8001"
      }
    }
  }
}

Auto save to config detected printers and other config changes

Auto save to config file appsettings.json all detected printers, for future use. Also will set AutoDetect = false, when there is at least one working printer available. This is because in the default case, for the user auto detection will be valuable only in that case. Of course is possible to force auto detection with AutoDetect = true in the config file. It is possible to have aliases, i.e. different PrinterId with the same Uri in the config file appsettings.json. There is new section in the appsettings.json, "ErpNet.FP" to be compatible with others, like "Kestrel", etc.. AutoDetect and Printers sub sections are under "ErpNet.FP" section now.

Keep the last 9 versions of debug.log

Each starting and stopping of the server creates a debug.log file.

The current task is to keep up to 9 previous versions of debug.log. E.g., keep the debug.log generated by the current and the previous 9 start-stop cycles.

Admin page and /service api

Improving admin page and service api.
Introducing server variables - /service/vars, forcing detection of printers - /service/detect, list of configured printers - /service/printers, configure new printer - /service/printers/configure and deleting/removing printer from configured printers list - /service/printers/delete
From admin page, with link to folder wwwroot/debug, the file debug.log and history of debug.log files - debug.log.[1-9].zip can be downloaded.

Get a unique workplace identifier

Get a unique workplace identifier on the device where the ErpNet.FP server is running.
By government requirements for workplaces, from annex 29 points 5, 8, 18, 18.1, 18.9.

It can also help for control fiscal devices usage - set defaults or restrict, when more than one available for a workplace.

For softwares without locally installed modules, it will eliminate the need to install an extra server to obtain workplace id.

Identifier may be a bios serial, drive serial, ethernet adapter or other unique identifier.
Response may be a hash, to keep a fixed length.

Example Request
GET: /deviceuid

Example Response

{
	"deviceuid": "2C290D367A8020BF6F75F5AB4B0E8F30"
}

Get the status of the last fiscal transaction


name: Feature request
about: Suggest an idea for this project
title: 'Get the status of the last fiscal transaction'
labels: 'enhancement'
assignees: ''


Is your feature request related to a problem? Please describe.
Frequently, there is a loss of connection with the software during printing. The ability to check the status of the last fiscal transaction any time after, will help to decide how to complete the sale.

Describe the solution you'd like
To have command which return the info of the last transaction. For example:
GET: /printers/dt525860/lasttransactionstatus

Describe alternatives you've considered
This is partially accomplished with asynchronous tasks, but it can not cover all cases.

Payments mapping

Payments mapping is hard coded
Current defaults cover only device defaults but companies can change payment name on every payment type. So we need some kind of setup of payments (probably in appsettings.json) for GetPaymentTypeText to avoid resetting of devices.

My suggestion is new optional object in appsettings under printers items
Example:

    "Printers" :  {
      "dt769373" :  {
        "Uri" : "bg.dt.p.isl.com://COM3"
        "PaymentTypes" :  {
          "card" :  "N",
          "cash" : "P",
          "packaging" : "I",
          "check" :  "C"
        }
      },
      "zk125928" :  {
        "Uri" : "bg.zk.zfp.com://COM2",
        "PaymentTypes" : {
          "card" : "7",
          "check" : "3",
          "cash" : "0",
          "packaging" : "4",
          "loyalty" : "2"
        }
      }
    }

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.