code: function _computeLevels(chars, levels, params) {
        var action,
            condition,
            i,
            index,
            newLevel,
            prevState,
            condPos = -1,
            len = chars.length,
            newState = 0,
            resolvedTypes = [],
            stateTable = _dir ? _STATE_TABLE_RTL : _STATE_TABLE_LTR,
            types = [];
        _lastArabic = false;
        _hasUbatB = false;
        _hasUbatS = false;
  
        for (i = 0; i < len; i++) {
          types[i] = _getCharType(chars[i]);
        }
  
        for (index = 0; index < len; index++) {
          prevState = newState;
          resolvedTypes[index] = _resolveCharType(chars, types, resolvedTypes, index);
          newState = stateTable[prevState][_TYPE_NAMES_MAP[resolvedTypes[index]]];
          action = newState & 0xF0;
          newState &= 0x0F;
          levels[index] = newLevel = stateTable[newState][5];
  
          if (action > 0) {
            if (action === 0x10) {
              for (i = condPos; i < index; i++) {
                levels[i] = 1;
              }
  
              condPos = -1;
            } else {
              condPos = -1;
            }
          }
  
          condition = stateTable[newState][6];
  
          if (condition) {
            if (condPos === -1) {
              condPos = index;
            }
          } else {
            if (condPos > -1) {
              for (i = condPos; i < index; i++) {
                levels[i] = newLevel;
              }
  
              condPos = -1;
            }
          }
  
          if (types[index] === "B") {
            levels[index] = 0;
          }
  
          params.hiLevel |= newLevel;
        }
  
        if (_hasUbatS) {
          _handleUbatS(types, levels, len);
        }
      }
docs: For reference see 3.3 in http://unicode.org/reports/tr9/