mirror of
				https://github.com/zyphlar/doorlock.git
				synced 2024-04-03 21:36:03 +00:00 
			
		
		
		
	using ajax for submission
This commit is contained in:
		
							parent
							
								
									f4de43ba68
								
							
						
					
					
						commit
						aa57b26a8b
					
				
							
								
								
									
										56
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										56
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							@ -5882,12 +5882,14 @@
 | 
			
		||||
            "balanced-match": {
 | 
			
		||||
              "version": "1.0.0",
 | 
			
		||||
              "bundled": true,
 | 
			
		||||
              "dev": true
 | 
			
		||||
              "dev": true,
 | 
			
		||||
              "optional": true
 | 
			
		||||
            },
 | 
			
		||||
            "brace-expansion": {
 | 
			
		||||
              "version": "1.1.11",
 | 
			
		||||
              "bundled": true,
 | 
			
		||||
              "dev": true,
 | 
			
		||||
              "optional": true,
 | 
			
		||||
              "requires": {
 | 
			
		||||
                "balanced-match": "^1.0.0",
 | 
			
		||||
                "concat-map": "0.0.1"
 | 
			
		||||
@ -5902,17 +5904,20 @@
 | 
			
		||||
            "code-point-at": {
 | 
			
		||||
              "version": "1.1.0",
 | 
			
		||||
              "bundled": true,
 | 
			
		||||
              "dev": true
 | 
			
		||||
              "dev": true,
 | 
			
		||||
              "optional": true
 | 
			
		||||
            },
 | 
			
		||||
            "concat-map": {
 | 
			
		||||
              "version": "0.0.1",
 | 
			
		||||
              "bundled": true,
 | 
			
		||||
              "dev": true
 | 
			
		||||
              "dev": true,
 | 
			
		||||
              "optional": true
 | 
			
		||||
            },
 | 
			
		||||
            "console-control-strings": {
 | 
			
		||||
              "version": "1.1.0",
 | 
			
		||||
              "bundled": true,
 | 
			
		||||
              "dev": true
 | 
			
		||||
              "dev": true,
 | 
			
		||||
              "optional": true
 | 
			
		||||
            },
 | 
			
		||||
            "core-util-is": {
 | 
			
		||||
              "version": "1.0.2",
 | 
			
		||||
@ -6029,7 +6034,8 @@
 | 
			
		||||
            "inherits": {
 | 
			
		||||
              "version": "2.0.3",
 | 
			
		||||
              "bundled": true,
 | 
			
		||||
              "dev": true
 | 
			
		||||
              "dev": true,
 | 
			
		||||
              "optional": true
 | 
			
		||||
            },
 | 
			
		||||
            "ini": {
 | 
			
		||||
              "version": "1.3.5",
 | 
			
		||||
@ -6041,6 +6047,7 @@
 | 
			
		||||
              "version": "1.0.0",
 | 
			
		||||
              "bundled": true,
 | 
			
		||||
              "dev": true,
 | 
			
		||||
              "optional": true,
 | 
			
		||||
              "requires": {
 | 
			
		||||
                "number-is-nan": "^1.0.0"
 | 
			
		||||
              }
 | 
			
		||||
@ -6055,6 +6062,7 @@
 | 
			
		||||
              "version": "3.0.4",
 | 
			
		||||
              "bundled": true,
 | 
			
		||||
              "dev": true,
 | 
			
		||||
              "optional": true,
 | 
			
		||||
              "requires": {
 | 
			
		||||
                "brace-expansion": "^1.1.7"
 | 
			
		||||
              }
 | 
			
		||||
@ -6062,12 +6070,14 @@
 | 
			
		||||
            "minimist": {
 | 
			
		||||
              "version": "0.0.8",
 | 
			
		||||
              "bundled": true,
 | 
			
		||||
              "dev": true
 | 
			
		||||
              "dev": true,
 | 
			
		||||
              "optional": true
 | 
			
		||||
            },
 | 
			
		||||
            "minipass": {
 | 
			
		||||
              "version": "2.2.4",
 | 
			
		||||
              "bundled": true,
 | 
			
		||||
              "dev": true,
 | 
			
		||||
              "optional": true,
 | 
			
		||||
              "requires": {
 | 
			
		||||
                "safe-buffer": "^5.1.1",
 | 
			
		||||
                "yallist": "^3.0.0"
 | 
			
		||||
@ -6086,6 +6096,7 @@
 | 
			
		||||
              "version": "0.5.1",
 | 
			
		||||
              "bundled": true,
 | 
			
		||||
              "dev": true,
 | 
			
		||||
              "optional": true,
 | 
			
		||||
              "requires": {
 | 
			
		||||
                "minimist": "0.0.8"
 | 
			
		||||
              }
 | 
			
		||||
@ -6166,7 +6177,8 @@
 | 
			
		||||
            "number-is-nan": {
 | 
			
		||||
              "version": "1.0.1",
 | 
			
		||||
              "bundled": true,
 | 
			
		||||
              "dev": true
 | 
			
		||||
              "dev": true,
 | 
			
		||||
              "optional": true
 | 
			
		||||
            },
 | 
			
		||||
            "object-assign": {
 | 
			
		||||
              "version": "4.1.1",
 | 
			
		||||
@ -6178,6 +6190,7 @@
 | 
			
		||||
              "version": "1.4.0",
 | 
			
		||||
              "bundled": true,
 | 
			
		||||
              "dev": true,
 | 
			
		||||
              "optional": true,
 | 
			
		||||
              "requires": {
 | 
			
		||||
                "wrappy": "1"
 | 
			
		||||
              }
 | 
			
		||||
@ -6299,6 +6312,7 @@
 | 
			
		||||
              "version": "1.0.2",
 | 
			
		||||
              "bundled": true,
 | 
			
		||||
              "dev": true,
 | 
			
		||||
              "optional": true,
 | 
			
		||||
              "requires": {
 | 
			
		||||
                "code-point-at": "^1.0.0",
 | 
			
		||||
                "is-fullwidth-code-point": "^1.0.0",
 | 
			
		||||
@ -11210,12 +11224,14 @@
 | 
			
		||||
            "balanced-match": {
 | 
			
		||||
              "version": "1.0.0",
 | 
			
		||||
              "bundled": true,
 | 
			
		||||
              "dev": true
 | 
			
		||||
              "dev": true,
 | 
			
		||||
              "optional": true
 | 
			
		||||
            },
 | 
			
		||||
            "brace-expansion": {
 | 
			
		||||
              "version": "1.1.11",
 | 
			
		||||
              "bundled": true,
 | 
			
		||||
              "dev": true,
 | 
			
		||||
              "optional": true,
 | 
			
		||||
              "requires": {
 | 
			
		||||
                "balanced-match": "^1.0.0",
 | 
			
		||||
                "concat-map": "0.0.1"
 | 
			
		||||
@ -11230,17 +11246,20 @@
 | 
			
		||||
            "code-point-at": {
 | 
			
		||||
              "version": "1.1.0",
 | 
			
		||||
              "bundled": true,
 | 
			
		||||
              "dev": true
 | 
			
		||||
              "dev": true,
 | 
			
		||||
              "optional": true
 | 
			
		||||
            },
 | 
			
		||||
            "concat-map": {
 | 
			
		||||
              "version": "0.0.1",
 | 
			
		||||
              "bundled": true,
 | 
			
		||||
              "dev": true
 | 
			
		||||
              "dev": true,
 | 
			
		||||
              "optional": true
 | 
			
		||||
            },
 | 
			
		||||
            "console-control-strings": {
 | 
			
		||||
              "version": "1.1.0",
 | 
			
		||||
              "bundled": true,
 | 
			
		||||
              "dev": true
 | 
			
		||||
              "dev": true,
 | 
			
		||||
              "optional": true
 | 
			
		||||
            },
 | 
			
		||||
            "core-util-is": {
 | 
			
		||||
              "version": "1.0.2",
 | 
			
		||||
@ -11357,7 +11376,8 @@
 | 
			
		||||
            "inherits": {
 | 
			
		||||
              "version": "2.0.3",
 | 
			
		||||
              "bundled": true,
 | 
			
		||||
              "dev": true
 | 
			
		||||
              "dev": true,
 | 
			
		||||
              "optional": true
 | 
			
		||||
            },
 | 
			
		||||
            "ini": {
 | 
			
		||||
              "version": "1.3.5",
 | 
			
		||||
@ -11369,6 +11389,7 @@
 | 
			
		||||
              "version": "1.0.0",
 | 
			
		||||
              "bundled": true,
 | 
			
		||||
              "dev": true,
 | 
			
		||||
              "optional": true,
 | 
			
		||||
              "requires": {
 | 
			
		||||
                "number-is-nan": "^1.0.0"
 | 
			
		||||
              }
 | 
			
		||||
@ -11383,6 +11404,7 @@
 | 
			
		||||
              "version": "3.0.4",
 | 
			
		||||
              "bundled": true,
 | 
			
		||||
              "dev": true,
 | 
			
		||||
              "optional": true,
 | 
			
		||||
              "requires": {
 | 
			
		||||
                "brace-expansion": "^1.1.7"
 | 
			
		||||
              }
 | 
			
		||||
@ -11390,12 +11412,14 @@
 | 
			
		||||
            "minimist": {
 | 
			
		||||
              "version": "0.0.8",
 | 
			
		||||
              "bundled": true,
 | 
			
		||||
              "dev": true
 | 
			
		||||
              "dev": true,
 | 
			
		||||
              "optional": true
 | 
			
		||||
            },
 | 
			
		||||
            "minipass": {
 | 
			
		||||
              "version": "2.2.4",
 | 
			
		||||
              "bundled": true,
 | 
			
		||||
              "dev": true,
 | 
			
		||||
              "optional": true,
 | 
			
		||||
              "requires": {
 | 
			
		||||
                "safe-buffer": "^5.1.1",
 | 
			
		||||
                "yallist": "^3.0.0"
 | 
			
		||||
@ -11414,6 +11438,7 @@
 | 
			
		||||
              "version": "0.5.1",
 | 
			
		||||
              "bundled": true,
 | 
			
		||||
              "dev": true,
 | 
			
		||||
              "optional": true,
 | 
			
		||||
              "requires": {
 | 
			
		||||
                "minimist": "0.0.8"
 | 
			
		||||
              }
 | 
			
		||||
@ -11494,7 +11519,8 @@
 | 
			
		||||
            "number-is-nan": {
 | 
			
		||||
              "version": "1.0.1",
 | 
			
		||||
              "bundled": true,
 | 
			
		||||
              "dev": true
 | 
			
		||||
              "dev": true,
 | 
			
		||||
              "optional": true
 | 
			
		||||
            },
 | 
			
		||||
            "object-assign": {
 | 
			
		||||
              "version": "4.1.1",
 | 
			
		||||
@ -11506,6 +11532,7 @@
 | 
			
		||||
              "version": "1.4.0",
 | 
			
		||||
              "bundled": true,
 | 
			
		||||
              "dev": true,
 | 
			
		||||
              "optional": true,
 | 
			
		||||
              "requires": {
 | 
			
		||||
                "wrappy": "1"
 | 
			
		||||
              }
 | 
			
		||||
@ -11627,6 +11654,7 @@
 | 
			
		||||
              "version": "1.0.2",
 | 
			
		||||
              "bundled": true,
 | 
			
		||||
              "dev": true,
 | 
			
		||||
              "optional": true,
 | 
			
		||||
              "requires": {
 | 
			
		||||
                "code-point-at": "^1.0.0",
 | 
			
		||||
                "is-fullwidth-code-point": "^1.0.0",
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										79
									
								
								public/client.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										79
									
								
								public/client.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,79 @@
 | 
			
		||||
$(function(){
 | 
			
		||||
    // refocus and clear the input box every 20sec
 | 
			
		||||
    setInterval(function(){
 | 
			
		||||
        $("#rfid").focus();
 | 
			
		||||
        $("#rfid").val(null);
 | 
			
		||||
    }, 20000);
 | 
			
		||||
 | 
			
		||||
    $("#rfid").keydown(function(event){
 | 
			
		||||
        // cancel enter keys
 | 
			
		||||
        if (event.keyCode === 13){
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // store value
 | 
			
		||||
        value = $("#rfid").val();
 | 
			
		||||
 | 
			
		||||
        // start processing after the first few chars
 | 
			
		||||
        if (value.length >= 5) {
 | 
			
		||||
            // wait to send the request for a sec to let them finish typing
 | 
			
		||||
            setTimeout(function(){
 | 
			
		||||
                // clear input box
 | 
			
		||||
                $("#rfid").val(null);
 | 
			
		||||
                // post value to server
 | 
			
		||||
                loading(true);
 | 
			
		||||
                $.post("/checkin", {"rfid":value}, function(data){
 | 
			
		||||
                    console.log(data);
 | 
			
		||||
                    if (data.hasOwnProperty("success")) {
 | 
			
		||||
                        if (data.success) {
 | 
			
		||||
                            success(data.name);
 | 
			
		||||
                        } else {
 | 
			
		||||
                            failure();
 | 
			
		||||
                        }
 | 
			
		||||
                    } else {
 | 
			
		||||
                        error();
 | 
			
		||||
                    }
 | 
			
		||||
                }, "json").fail(function(){
 | 
			
		||||
                    error();
 | 
			
		||||
                }).always(function(){
 | 
			
		||||
                    loading(false);
 | 
			
		||||
                });
 | 
			
		||||
            }, 250);
 | 
			
		||||
        }
 | 
			
		||||
    });
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
function loading(loading){
 | 
			
		||||
    if (loading) {
 | 
			
		||||
        $("#loading").removeClass("dn");
 | 
			
		||||
    } else {
 | 
			
		||||
        $("#loading").addClass("dn");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function reset(){
 | 
			
		||||
    $("#name").text(null);
 | 
			
		||||
    $("#failure").addClass("dn");
 | 
			
		||||
    $("#success").addClass("dn");
 | 
			
		||||
    $("#error").addClass("dn");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function success(name){
 | 
			
		||||
    reset();
 | 
			
		||||
    $("#name").text(name);
 | 
			
		||||
    $("#success").removeClass("dn");
 | 
			
		||||
    setTimeout(function(){ reset(); }, 5000);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function failure(){
 | 
			
		||||
    reset();
 | 
			
		||||
    $("#failure").removeClass("dn");
 | 
			
		||||
    setTimeout(function(){ reset(); }, 5000);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function error(){
 | 
			
		||||
    reset();
 | 
			
		||||
    $("#error").removeClass("dn");
 | 
			
		||||
    setTimeout(function(){ reset(); }, 5000);
 | 
			
		||||
}
 | 
			
		||||
@ -65,7 +65,7 @@ Or generally, find some way to run `./start.sh` in this folder
 | 
			
		||||
 | 
			
		||||
## Further reading
 | 
			
		||||
 | 
			
		||||
-   [USB Relay librar](https://github.com/darrylb123/usbrelay)
 | 
			
		||||
-   [USB Relay library](https://github.com/darrylb123/usbrelay)
 | 
			
		||||
-   https://obrienlabs.net/setup-raspberry-pi-kiosk-chromium/
 | 
			
		||||
 | 
			
		||||
## Contributing
 | 
			
		||||
@ -88,4 +88,4 @@ MIT
 | 
			
		||||
[dana]: http://danawoodman.com
 | 
			
		||||
[jest]: https://facebook.github.io/jest
 | 
			
		||||
[latch]: https://www.amazon.com/gp/product/B00V45GWTI
 | 
			
		||||
[start]: http://tessel.github.io/t2-start
 | 
			
		||||
[relay]: http://a.co/d/hbuockB
 | 
			
		||||
 | 
			
		||||
@ -28,31 +28,6 @@ module.exports = class Cards {
 | 
			
		||||
    return this.all().then(cards =>
 | 
			
		||||
      cards.find(c => parseInt(c.number, 10) === parseInt(number, 10))
 | 
			
		||||
    )
 | 
			
		||||
    // console.log(':', JSON.stringify(number.toString().trim()))
 | 
			
		||||
    // const scanned = parseInt(
 | 
			
		||||
    //   number
 | 
			
		||||
    //     .toString('hex')
 | 
			
		||||
    //     .trim() // Remove any whiespace or newlines
 | 
			
		||||
    //     .replace('\u0003', '') // Remove "end of text" character
 | 
			
		||||
    //     .replace('\u0002', '') // Remove "start of text" character
 | 
			
		||||
    //     .substring(3) // Strip off con
 | 
			
		||||
    //     .slice(0, -2), // Strip off checksum
 | 
			
		||||
    //   16
 | 
			
		||||
    // )
 | 
			
		||||
 | 
			
		||||
    // this.log('Scanned card:', scanned)
 | 
			
		||||
 | 
			
		||||
    // return this.readCardsFromSDCard().then(cards => {
 | 
			
		||||
    //   const card = cards.find(c => parseInt(c.number) === scanned)
 | 
			
		||||
 | 
			
		||||
    //   if (card) {
 | 
			
		||||
    //     const name = card.name.split(' ')[0]
 | 
			
		||||
    //     this.log(`Welcome in ${name}!`, scanned)
 | 
			
		||||
    //     this.openDoor()
 | 
			
		||||
    //   } else {
 | 
			
		||||
    //     this.log('Card is invalid:', scanned)
 | 
			
		||||
    //   }
 | 
			
		||||
    // })
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  static sortByName(cards) {
 | 
			
		||||
 | 
			
		||||
@ -7,7 +7,7 @@ module.exports = class Logs {
 | 
			
		||||
  static all() {
 | 
			
		||||
    return new Promise((resolve, reject) => {
 | 
			
		||||
      fs.readFile(LOGS_PATH, (err, data) => {
 | 
			
		||||
        if (err) return reject(err)
 | 
			
		||||
        if (err) return resolve(JSON.parse("[]"))
 | 
			
		||||
        resolve(JSON.parse(data))
 | 
			
		||||
      })
 | 
			
		||||
    })
 | 
			
		||||
 | 
			
		||||
@ -8,12 +8,26 @@ module.exports = (req, res) => {
 | 
			
		||||
 | 
			
		||||
  Cards.validate(rfid).then(card => {
 | 
			
		||||
    console.log('CARD:', card)
 | 
			
		||||
    if (!card) return res.redirect('/failure')
 | 
			
		||||
    if (!card) return reponse(req,res,'/failure',false)
 | 
			
		||||
 | 
			
		||||
    res.redirect('/success?name=' + card.name)
 | 
			
		||||
    reponse(req,res,'/success?name=' + card.name,true,card.name)
 | 
			
		||||
    Logs.log({ timestamp: new Date().getTime(), card }).then(() =>
 | 
			
		||||
      console.log('Logged!')
 | 
			
		||||
    )
 | 
			
		||||
    Door.open()
 | 
			
		||||
  }).catch(err => {
 | 
			
		||||
    reponse(req,res,'/failure',false)
 | 
			
		||||
    Logs.log({ timestamp: new Date().getTime(), err}).then(() =>
 | 
			
		||||
      console.log('Undefined failure: '+err)
 | 
			
		||||
    )
 | 
			
		||||
  })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function reponse(req,res,path,success,name=null) {
 | 
			
		||||
  console.log(req.get('accept'));
 | 
			
		||||
  if(/application\/json/.test(req.get('accept'))) {
 | 
			
		||||
    res.json({"success":success, "path":path})
 | 
			
		||||
  } else {
 | 
			
		||||
    res.redirect(path)
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@ -19,4 +19,4 @@ block content
 | 
			
		||||
      for card in cards
 | 
			
		||||
        tr.hov-bg-gray-lightest
 | 
			
		||||
          td.px-md.py-sm.bb.bc-gray-lighter= card.name
 | 
			
		||||
          td.px-md.py-sm.bb.bc-gray-lighter= card.number
 | 
			
		||||
          td.px-md.py-sm.bb.bc-gray-lighter= parseInt(card.number, 10)
 | 
			
		||||
 | 
			
		||||
@ -7,3 +7,35 @@ block content
 | 
			
		||||
  h1.page-heading Scan Your Card
 | 
			
		||||
  form(action='/checkin' method='post')
 | 
			
		||||
    input#rfid.input.input-block(name="rfid" autofocus)
 | 
			
		||||
 | 
			
		||||
  section#failure.dn
 | 
			
		||||
    .df.ai-center.jc-center.bg-danger.white.px-lg.py-md
 | 
			
		||||
      i.fas.fa-times.mr-lg.txt-xxl
 | 
			
		||||
      .f-1
 | 
			
		||||
        .txt-xl Card not valid
 | 
			
		||||
        .mt-sm.danger-lighter Sorry your card isn't valid. Please try again.
 | 
			
		||||
        .mt-sm.danger-lighter
 | 
			
		||||
          em Maybe your membership has expired?
 | 
			
		||||
 | 
			
		||||
  section#success.dn
 | 
			
		||||
    .df.ai-center.jc-center.bg-success.white.px-lg.py-md
 | 
			
		||||
      i.fas.fa-check.mr-lg.txt-xxl
 | 
			
		||||
      .f-1
 | 
			
		||||
        .txt-xl
 | 
			
		||||
          | Welcome in 
 | 
			
		||||
          span#name
 | 
			
		||||
          | !
 | 
			
		||||
        .mt-sm.success-lighter Have an awesome day of making!
 | 
			
		||||
 | 
			
		||||
  section#error.dn
 | 
			
		||||
    .df.ai-center.jc-center.bg-warning.white.px-lg.py-md
 | 
			
		||||
      i.fas.fa-exclamation.mr-lg.txt-xxl
 | 
			
		||||
      .f-1
 | 
			
		||||
        .txt-xl Error
 | 
			
		||||
        .mt-sm.warning-lighter Something went wrong with the card reader.
 | 
			
		||||
        .mt-sm.warning-lighter
 | 
			
		||||
          em We're sorry. Please contact a volunteer.
 | 
			
		||||
 | 
			
		||||
  section#loading.dn
 | 
			
		||||
    .df.ai-center.jc-center.px-lg.py-md
 | 
			
		||||
      i.fas.fa-spinner.fa-spin.mr-lg.txt-xxl
 | 
			
		||||
 | 
			
		||||
@ -9,6 +9,8 @@ html(lang='en')
 | 
			
		||||
    link(href='//unpkg.com/euphoria/dist/euphoria.min.css' rel='stylesheet' type='text/css')
 | 
			
		||||
    link(href='https://use.fontawesome.com/releases/v5.0.13/css/all.css' rel='stylesheet' integrity='sha384-DNOHZ68U8hZfKXOrtjWvjxusGo9WQnrNx2sqG0tfsghAvtVlRW3tvkXWZh58N9jp' crossorigin='anonymous')
 | 
			
		||||
    link(href='/styles.css' rel='stylesheet')
 | 
			
		||||
    script(src='http://code.jquery.com/jquery-latest.min.js')
 | 
			
		||||
    script(src='/client.js')
 | 
			
		||||
 | 
			
		||||
  body.p-none.m-none.ff-sans-serif
 | 
			
		||||
    header.df.p-md.gray.bb.bc-gray-lighter
 | 
			
		||||
 | 
			
		||||
@ -17,5 +17,8 @@ block content
 | 
			
		||||
        - date = new Date(log.timestamp)
 | 
			
		||||
        tr.hov-bg-gray-lightest
 | 
			
		||||
          td.px-md.py-sm.bb.bc-gray-lighter.c-help(title=date)= moment(date).fromNow()
 | 
			
		||||
          td.px-md.py-sm.bb.bc-gray-lighter= log.card.name
 | 
			
		||||
          td.px-md.py-sm.bb.bc-gray-lighter= log.card.number
 | 
			
		||||
          td.px-md.py-sm.bb.bc-gray-lighter= log.card ? log.card.name : ""
 | 
			
		||||
          td.px-md.py-sm.bb.bc-gray-lighter= log.card ? log.card.number : ""
 | 
			
		||||
          td.px-md.py-sm.bb.bc-gray-lighter= log.err ? log.err.code : ""
 | 
			
		||||
          td.px-md.py-sm.bb.bc-gray-lighter= log.err ? log.err.syscall : ""
 | 
			
		||||
          td.px-md.py-sm.bb.bc-gray-lighter= log.err ? log.err.path : ""
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user