Pen Settings

HTML

CSS

CSS Base

Vendor Prefixing

Add External Stylesheets/Pens

Any URL's added here will be added as <link>s in order, and before the CSS in the editor. If you link to another Pen, it will include the CSS from that Pen. If the preprocessor matches, it will attempt to combine them before processing.

+ add another resource

JavaScript

Babel includes JSX processing.

Add External Scripts/Pens

Any URL's added here will be added as <script>s in order, and run before the JavaScript in the editor. You can use the URL of any other Pen and it will include the JavaScript from that Pen.

+ add another resource

Packages

Add Packages

Search for and use JavaScript packages from npm here. By selecting a package, an import statement will be added to the top of the JavaScript editor for this package.

Behavior

Save Automatically?

If active, Pens will autosave every 30 seconds after being saved once.

Auto-Updating Preview

If enabled, the preview panel updates automatically as you code. If disabled, use the "Run" button to update.

Format on Save

If enabled, your code will be formatted when you actively save your Pen. Note: your code becomes un-folded during formatting.

Editor Settings

Code Indentation

Want to change your Syntax Highlighting theme, Fonts and more?

Visit your global Editor Settings.

HTML

              
                <body class="container-fluid">
<div id="main" class="row">
 <div id="chalculator" class="col-sm-12 col-med-7 col-lg-8">
  <ul id="TheTabs" class="nav nav-tabs" role="tablist">
    <li class="nav-item" role="presentation">
      <a class="nav-link" id="peopletab" data-toggle="tab" href="#people" role="tab" aria-controls="people" aria-selected="true">People</a>
    </li>
    <li class="nav-item" role="presentation">
      <a class="nav-link" id="thingstab" data-toggle="tab" href="#things" role="tab" aria-controls="things" aria-selected="false">Things</a>
    </li>
   </ul>
  <div id="TheTabsContent" class="tab-content">
   <div class="tab-pane active" id="people" role="tabpanel" aria-labelledby="peopletab" style="display:none">
    <div id="people-inputs" class="row">
     <label for="nameInput">Birth Name: </-label>
     <input type="text" id="nameInput" placeholder="Enter Birth Name"/>
     <label for="bdInput" style="margin-left:10px">Birth Date: </label>
     <input type="text" id="bdInput" placeholder="mm/dd/yyyy"/>
    </div>
    <div id="people-buttons" class="row">
     <button id="chalculate" class="btn btn-primary col-sm-2">Chalculate</button>
     <p class="instr col-sm-8">Enter a birth name and date, then click "Chalculate"</p>
     <button id="chalcclear" class="btn btn-secondary col-sm-2">Clear</button>
    </div>
    <table class="table" width=68%>
     <colgroup>
      <col width="15%">
      <col width="10%">
      <col width="25%">
      <col width="10%">
     </colgroup>
     <tbody>
      <tr>
       <th>Aspect</th>
       <th>Vibration</th>
       <th>Interpretation</th>
       <th>Composition</th>
      </tr>
      <tr id="purpose"><td>Purpose</td></tr>
      <tr id="heart"><td>Heart</td></tr>
      <tr id="persona"><td>Persona</td></tr>
      <tr id="destiny"><td>Destiny</td></tr>
      <tr id="goal"><td>Goal</td></tr>
     </tbody>
    </table>
   </div> 
   <div class="tab-pane" id="things" role="tabpanel" aria-labelledby="thingstab" style="display:none">
     <h4>Things</h4>
     <div id="miscinputs" class="row">
       <label class="col-sm-1" for="miscInput">Thing: </label>
       <input type="text" id="miscInput" placeholder="Enter something" class="col-sm-6"/>
       <button id="miscchalculate" class="btn btn-primary col-sm-2">Chalculate</button>
     </div>
     <div id="miscvibration" class="misc"></div>
     <div id="misctranslation" style="text-align:center;height:3em;padding-top:1em"></div>
     <div id="misccomposition" style="text-align:center;height:3em;padding-top:1em"></div>
   </div>
  </div>
 </div>
 <div id="chat" class="col-sm-12 col-md-5 col-lg-4">
  <strong>Chat</strong>
  <div id="parts" class="row"></div>
  <ol id="messages" >
  </ol>
  <div id="entry" class="row">
   <!-- <label for="msg" class="col-sm-3">Message</label> -->
   <input id="msg" type="text" placeholder="Type a message" class="col-sm-12"/>
   <div id="actions" class="row">
    <button id="btnsend" class="btn btn-primary col-sm-12">Send</button>
    <button id="btnclear" class="btn btn-warning col-sm-9">Clear All Messages</button>
    <button id="btnexit" class="btn btn-danger col-sm-3">Exit</button>
   </div>
  </div>
 </div>
</div>
<div id="errors" class="row" style="color:red;margin:3em"></div>
<div id="caveat" class="row" style="margin-top:2em">
 <h5>For entertainment purposes ONLY. No warranty expressed or implied</h5>
</div>
<div id="legal" class="row">
 <h6>Copyright 2020 John McKeon. All rights reserved.</h6>
</div>

              
            
!

CSS

              
                #widgets {float: right; width: 200; height: 200}
th { font-size:75% }
td.eleven { background-color: yellow; }
td.twentytwo { background-color: red; color:white }
#parts { height:5em;
     border:solid 1px gray;
      border-radius: 8px;
      width: 90%;
      margin-left: 10px;
     overflow-y:auto; }
#parts ul { padding-left:10px }
#messages { height:20em;border:solid 1px gray;overflow-y:scroll }
#messages, #actions { padding-left:10px }
#purpose,#heart,#persona,#destiny,#goal { font-weight:bold }
small { display:hidden }
ol { list-style-type="None" item-height: 25px}
ol#messages li { width: 100%; height: 2em; overflow-y: scroll; padding: 6px }
div.misc { text-align:center;height:3em;padding-top:1em }
label,p.instr { font-size: small; color: lightslategray; margin: 5px; display: inline; }

              
            
!

JS

              
                //Chalculator-the Chaldean calculator
//Copyright John McKeon
//All rights reserved

var interpretations = new Map();
interpretations.set("Purpose",['Leader','Diplomat','Creator','Bullder','Traveller','Teacher','Thinker','Judge','Healer','Visionary','Statesman']);
interpretations.set("Heart",['Pioneering','Friendly','Self Expression','Practical','Variety','Love','Intellect','University','Invention','Idealism']);
interpretations.set("Persona",["Independent","Agreeable","Sociable","Practical","Adventurous","Contemplative","Intelligent","Ambitious","Sincere","Idealistic","Midas"]);
interpretations.set("Destiny",["Innovator","Peacemaker","Entertainer","Builder","Investigator","Counselor","Spiritualist","Executive","Humanitarian","Enlightenment","Master Builder"]);
interpretations.set("Goal",['Leadership','Advisor','Speaker','Fountainhead','Freedom','Teacher','Philosopher','Judge','Healer','Oracle','Statesman']);
var chalcString = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
var chalcValues = "01234567891234583511234578123466651712345835112345781234666517";

String.prototype.reduced = function() {
  var c,x,rslt=0;
  for (let i=0; i<this.length; i++) {
    c=this[i];
    x=chalcString.indexOf(c);
    if (x<0) { continue };
    rslt+=Number(chalcValues[x]);
  };
  while ((rslt.reduced()>9)&&(!rslt.reduced().isGreatNumber())) { rslt = rslt.reduced() }
  return rslt;
};
  
Number.prototype.isGreatNumber = function(){
  return (this==11||this==22)
}
Number.prototype.reduced = function() {
  console.log(this)
  if (this.isGreatNumber()) { return this };
  var c,r=0;
  var s=this.toString();
  for (let i=0; i<s.length; i++) {
    c=s[i];
    r+=Number(c);
  };
  return r;
};

Number.prototype.interpretation = function(aspect) {
  if ((this==0)||(this>11)) { return "Bad Reduction!!" };
  var m = interpretations.get(aspect);
  if (!m) { return "Bad map" };
  return m[this - 1];
};

function span(width,text,klass) {
  if (klass) { return "<td class=\""+klass+"\">"+text+"</td>" }
  return "<td>"+text+"</td>"
  //return "<div class=\"col-sm-"+width+"\">"+text+"</div>"
};

String.prototype.chalculate = function(aspect) {
  var sum = this.reduced();
  while (sum.toString().length > 2) {
    sum = sum.reduced();
    if ((sum==11)||(sum==22)) { break };
  }
  var i=0,n=sum.reduced();
  if ((n==11)||(n==22)) { i = (n==11)?10:11 }
  else { 
    while (n.toString().length >1) { 
      sum = n;
      n = n.reduced();
    };
    i=n;
  };
  if ((n==11)||(n==22)) {
    var klass=(n==11)?"eleven":"twentytwo";
    return span(2,aspect,klass) + span(1,n.toString(),klass) + span(3,i.interpretation(aspect),klass) + span(3,"[ " + sum.toString() + " ]",klass);
  };
  return span(2,aspect) + span(1,n.toString()) + span(3,i.interpretation(aspect)) + span(3,"[ " + sum.toString() + " ]");
};

var vowels="aeiouAEIOU",consonants="bcdfghjklmnpqrstvwxyzBCDFGHJKLMNPRSTVWXYZ";
String.prototype.vowels=function(){
  var r="";
  for (let i=0; i<this.length; i++) {
    if (vowels.indexOf(this[i]) > -1) { r+=this[i] }
  }
  return r
};

String.prototype.consonants=function() {
  var r="";
  for (let i=0; i<this.length; i++) {
    if (consonants.indexOf(this[i]) > -1) { r+=this[i] }
  }
  return r;
};

class ChalcModel extends Croquet.Model {
  init() {
    //People vars
    this.birthName="";
    this.birthDate="";
    this.birthMonth=0;
    this.birthDay=0;
    this.birthYear=0;
    this.purpose="<td>Purpose</td>";
    this.heart="<td>Heart</td>";
    this.persona="<td>Persona</td>";
    this.destiny="<td>Destiny</td>";
    this.goal="<td>Goal</td>";
    
    //Things vars
    this.miscVibration=""
    this.miscTranslation=""
    this.miscCompostion=""
    
    //Chat
    this.views=new Map();
    this.history=new Array();
    this.currentTab="people";
    
    //Subscriptions
    this.subscribe("chalculate","chalculate",this.chalculate);
    this.subscribe("chalculate","chalcclear",this.clearProfile);
    this.subscribe("chalculate","misc",this.miscChalculate)
    this.subscribe(this.sessionId,"view-join",this.viewJoin);
    this.subscribe(this.sessionId,"view-exit",this.viewLeave);
    this.subscribe("post","msg",this.newMessage);
    this.subscribe("post","clear",this.clearHistory);
    this.subscribe("tabs","change",this.changeTabs)
  }

  chalculate(data) {
    var vals = data.split(";");
    if (vals.length != 2) { this.doError("We have a BIG problem"); return }
    this.birthName = vals[0];
    this.birthDate = vals[1];
    if (this.birthName == "") { this.doError("Birth Name cannot be blank"); return }
    if (this.birthDate == "") { this.doError("Birth Date cannot be blank"); return }
    var dateNumbers = this.birthDate.split("/");
    if (dateNumbers.length != 3) { this.doError("Birth Date is invalid"); return };
    var bm = Number(dateNumbers[0]);
    var bd = Number(dateNumbers[1]);
    var by = Number(dateNumbers[2]);
    if (Number.isNaN(bm)) { this.doError("Month is invalid"); return; }
    if (Number.isNaN(bd)) { this.doError("Day is invalid"); return; }
    if (Number.isNaN(by)) { this.doError("Year is not valid"); return; };
    if (bm < 1)  { this.doError("Month must be from 1 to 12"); return };
    if (bm > 12) { this.doError("Month must be from 1 to 12"); return };
    if (bd < 1)  { this.doError("Day must be from 1 to 31"); return };
    if (bd > 31) { this.doError("Day must be from 1 to 31"); return };
    this.birthMonth = bm;
    this.birthDay = bd;
    this.birthYear = by;
    this.purpose=this.birthName.chalculate("Purpose");
    this.heart=this.birthName.vowels().chalculate("Heart");
    this.persona=this.birthName.consonants().chalculate("Persona");
    this.destiny=this.birthDate.chalculate("Destiny");
    this.goal=(this.birthName + this.birthDate).chalculate("Goal");
    this.publish("update","profile");
  }
  
  miscChalculate(data) {
    this.miscComposition=data.reduced()
    this.miscVibration=this.miscComposition.reduced()
    var idx=(this.miscVibration!=11&&this.miscVibration!=22)?
        this.miscVibration:((this.miscVibration=11)?10:11)
    if (idx>=1&&idx<=11){
      this.miscTranslation=idx.interpretation("Heart")
    } else {
      this.miscTranslation="An error occurred"  
    }
    this.publish("update","things")
  }

  clearProfile() {
    this.birthName="";
    this.birthDate="";
    this.purpose="<td>Purpose</td>";
    this.heart="<td>Heart</td>";
    this.persona="<td>Persona</td>";
    this.destiny="<td>Destiny</td>";
    this.goal="<td>Goal</td>";
    this.publish("update","profile");
  }

  doError(data) { this.publish("update","error",data); }

  viewJoin(viewId) {
    var exists=this.views.get(viewId);
    if (!exists) {
      var sz=this.views.size;
      var nm=(sz==0)?"Numerologist":"Visitor"+sz;
      this.views.set(viewId,nm);
      if (this.views.size==1) {
        this.clearHistory();
      }
      this.publish("update","users");
    }
  }

  viewLeave(viewId) {
    this.views.delete(viewId);
    this.publish("update","users");
  }

  newMessage(data) {
    this.history.push(data);
    if (this.history.length>50) { this.history.shift() };
    this.publish("update","history");
  }

  clearHistory() {
    this.history=[];
    this.publish("update","history");
  }
  
  changeTabs(data) {
    this.currentTab = data
    this.publish("update","tabs");
  }
}

ChalcModel.register();

class ChalcView extends Croquet.View {
  constructor(model) {
    super(model);
    this.model = model;
    
    //Tabs
    peopletab.onclick = event => this.onTabs("people");
    thingstab.onclick = event => this.onTabs("things");

    //People tab
    chalculate.onclick = event => this.onClick(event);
    chalcclear.onclick = event => this.onClear(event);
    
    //Things tab
    miscchalculate.onclick = event => this.chalcMisc(event);
    
    //Chat
    btnsend.onclick = event => this.send(event);
    btnclear.onclick = event => this.clear(event);
    btnexit.onclick = event => this.exit(event);
    msg.onkeyup = event => this.keyup(event);
    this.subscribe("update","profile",this.updateProfile);
    this.subscribe("update","error",this.updateErrors);
    this.subscribe("update","users",this.refreshUsers);
    this.subscribe("update","history",this.refreshHistory);
    this.subscribe("update","tabs",this.updateTabs)
    this.subscribe("update","things",this.updateThings)
    this.updateProfile();
    this.refreshUsers();
    this.refreshHistory();
    this.updateTabs();
    
  }

  onClick() {
    errors.innerText = "";  //Clear any prior errors
    var data = nameInput.value + ";" + bdInput.value;
    this.publish("chalculate","chalculate",data);
  }

  onClear() {
    this.publish("chalculate","chalcclear");
  }

  updateProfile() {
    nameInput.value = this.model.birthName;
    bdInput.value = this.model.birthDate;
    purpose.innerHTML = this.model.purpose;
    heart.innerHTML = this.model.heart;
    persona.innerHTML = this.model.persona;
    destiny.innerHTML = this.model.destiny;
    goal.innerHTML = this.model.goal;
  }
    
  chalcMisc() {
    this.publish("chalculate","misc",miscInput.value)
  }
  
  updateThings(data) {
    miscvibration.innerHTML="<h2>"+this.model.miscVibration+"</h2>";
    misctranslation.innerHTML="<h4>"+this.model.miscTranslation+"</h4>";
    misccomposition.innerHTML="<h6>"+this.model.miscComposition+"</h6>";
  }
  
  updateErrors(data) { errors.innerText = data }

  refreshUsers(event) {
    var html="<ul style=\"list-style-type:none\">";
    for (let val of this.model.views.values()) {
      html+="<li><strong>"+val+"</strong></li>";
    };
    html+="</ul>";
    parts.innerHTML=html;
  }

  refreshHistory() {
    var html="";  //<ul style=\"list-style-type:none\">";
    for (let i=0; i<this.model.history.length; i++) {
      var item=this.model.history[i], a = item.split(";");
      if (a.length!=2) { continue };
      var nm=this.model.views.get(a[0]);
      if (!nm) { nm="unknown" };
      html+="<li><small>"+ nm +"</small>: "+a[1]+" <sub>("+a[1].reduced().reduced()+")</sub></li>";
    };
    messages.innerHTML=html;
    messages.scrollTop = Math.max(10000, messages.scrollHeight);
  }

  send() {
    if (msg.value == "") { return };
    var sender = this.model.views.get(this.viewId);
    this.publish("post","msg",this.viewId + ";" + msg.value);
    msg.value = "";
  }

  clear() {
    var ans=confirm("Are you sure you want to clear all messages?");
    if (!ans) { return };
    this.publish("post","clear");
    messages.innerHTML = "<p>No messages</p>";
  }
  
  keyup(event) {
    if (event.keyCode == 13) { this.send(event); }
  }

  onTabs(data) {
    this.publish("tabs","change",data)
  }
  
  updateTabs() {
    if (this.model.currentTab=="people") {
      people.style.display="block"
      peopletab.classList.add("active")
      things.style.display="none"
      thingstab.classList.remove("active")
      return
    } 
    if (this.model.currentTab=="things") {
      people.style.display="none"
      peopletab.classList.remove("active");
      things.style.display="block"
      thingstab.classList.add("active");
    }
  }

  exit() {
    this.session.leave();
  }
}

Croquet.Session.join("chalculator",ChalcModel,ChalcView);


              
            
!
999px

Console